【问题标题】:Find a Database table's unique constraint查找数据库表的唯一约束
【发布时间】:2010-12-13 01:15:45
【问题描述】:

我正在尝试使用 Java 查找表的唯一约束(在 Oracle 数据库上,但这应该没有区别)。

感谢 DatabaseMetaData 的 getPrimaryKeys(....); 但是我无法找到表格的独特内容,互联网也无法帮助我,因此我在这里结束了我的问题:)

有没有一种干净的方法来查找表的唯一约束(或者,更确切地说,是表必须是唯一的列的名称。嗯,你明白了,呵呵)? 最好的问候,

尼尔斯

【问题讨论】:

  • 所以我猜你宁愿没有特定于 Oracle 的解决方案?

标签: java sql oracle unique constraints


【解决方案1】:

由于大多数数据库将这些约束存储为索引,因此您可以使用前面提到的DatabaseMetaData.getIndexInfo()。这在我使用 Postgresql 时效果很好。

如文档所述,使用第 4 个参数为 true 调用 getIndexInfo() 很重要:

unique - 如果为真,则只返回唯一值的索引;假的时候, 无论是否唯一,都返回索引

使用以下代码:

// Class to combine all columns for the same index into one object
public static class UniqueConstraint {
    public String table;
    public String name;
    public List<String> columns = new ArrayList<>();
    public String toString() {
        return String.format("[%s] %s: %s", table, name, columns);
    }
}

public static List<UniqueConstraint> getUniqueConstraints(Connection conn, String schema, String table) throws SQLException {
    Map<String, UniqueConstraint> constraints = new HashMap<>();

    DatabaseMetaData dm = conn.getMetaData();
    ResultSet rs = dm.getIndexInfo(null, schema, table, true, true);
    while(rs.next()) {
        String indexName = rs.getString("index_name");
        String columnName = rs.getString("column_name");

        UniqueConstraint constraint = new UniqueConstraint();
        constraint.table = table;
        constraint.name = indexName;
        constraint.columns.add(columnName);

        constraints.compute(indexName, (key, value) -> {
            if (value == null) { return constraint; }
            value.columns.add(columnName);
            return value;
        });
    }

    return new ArrayList<>(constraints.values());
}

你可以打电话:

getUniqueConstraints(conn, "public", tableName);

并获取给定表的所有唯一约束的列表。约束是按索引分组的,因为一个索引可以覆盖多列,前提是它们组合起来是唯一的。

【讨论】:

    【解决方案2】:

    可以查询数据字典:

    SQL> SELECT cc.*
      2    FROM all_constraints c
      3    JOIN all_cons_columns cc ON (c.owner = cc.owner
      4                             AND c.constraint_name = cc.constraint_name)
      5   WHERE c.constraint_type = 'U'
      6     AND c.table_name = 'T';
    
    OWNER      CONSTRAINT_NAME   TABLE_NAME     COLUMN_NAME     POSITION
    ---------- ----------------- -------------- ------------- ----------
    VNZ        UNIQUE_COL        T              COLUMN1                1
    VNZ        UNIQUE_COL        T              COLUMN2                2
    VNZ        UNIQUE_COL2       T              COLUMN2                1
    

    【讨论】:

    • 感谢文森特,这正是我想要的!非常感谢!
    【解决方案3】:

    唯一约束通常由索引强制执行。也许使用DatabaseMetaData.getIndexInfo() 来查找非唯一为假的索引?

    【讨论】:

      【解决方案4】:

      如果 Oracle 为唯一约束创建索引(我不知道是否这样做,您需要检查),那么您可以通过 getIndexInfo() 了解您的约束

      【讨论】:

      • 是的,Oracle 在 UNIQUE 约束中标识的任何列上创建唯一索引 - 这就是它强制唯一性的方式。
      • 但是,唯一索引可能完全以 Oracle 为中心。如果需要通用解决方案,则可能并非在所有情况下都是如此。
      • 而且,我认为 Oracle 还可以使用非唯一索引来强制执行唯一约束。
      猜你喜欢
      • 2017-04-29
      • 2013-05-21
      • 2013-11-11
      • 2019-10-10
      • 1970-01-01
      • 2016-05-01
      • 1970-01-01
      • 2021-01-22
      • 2018-02-02
      相关资源
      最近更新 更多