查找数据库表的唯一约束条件

8
我正在尝试使用Java(在Oracle数据库上)查找表的唯一约束条件,但这应该没有什么区别。
我发现了一种方法来发现表的主键,感谢DatabaseMetaData的getPrimaryKeys(....)方法。然而,我无法找到表的唯一约束条件,并且互联网也无法帮助我,因此我在这里提出我的问题 :)
有没有一种简单的方法来查找表的唯一约束条件(或者更确切地说,必须唯一的列的名称..好吧,你懂的哈)? 最好的问候,
尼尔斯

那么我猜你不想要一个特定于Oracle的解决方案? - DCookie
4个回答

20

您可以查询数据字典:

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

2
由于大多数数据库将这些约束作为索引存储,因此您可以像先前提到的那样使用 DatabaseMetaData.getIndexInfo()。在我使用Postgresql时,这很有效。
只有在文档中说明时,才需要使用第4个参数true来调用getIndexInfo()

unique - 当为true时,仅返回唯一值的索引;当为false时,返回无论是否唯一的索引

使用以下代码:
// 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);

获取给定表的所有唯一约束条件列表。由于一个索引可以覆盖多个列,如果它们仅在组合中是唯一的,则将约束条件分组。


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

是的,Oracle会在任何在唯一约束中标识的列上创建唯一索引 - 这就是它强制实施唯一性的方式。 - DCookie
然而,唯一索引可能完全是Oracle中心的。如果需要通用解决方案,则在所有情况下可能并非如此。 - DCookie
我认为Oracle也可以使用非唯一索引来强制执行唯一约束。 - erikkallen

0

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接