Java 查找数据库表';s唯一约束

Java 查找数据库表';s唯一约束,java,sql,oracle,unique,constraints,Java,Sql,Oracle,Unique,Constraints,我正在尝试使用Java(在Oracle数据库上,但这应该没有什么区别)查找表的唯一约束 由于DatabaseMetaData的getPrimaryKeys(..),我找到了一种发现表主键的方法; 然而,我无法找到桌子的独特结构,互联网也无法帮助我,因此我在这里结束提问:) 有没有一种干净的方法可以找到一个表的唯一约束(或者,更确切地说,对于一个表来说,列的名称必须是唯一的..嗯,你明白了,呵呵)呢? 致以最良好的祝愿 Nils您可以查询数据字典: SQL> SELECT cc.* 2

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

由于DatabaseMetaData的getPrimaryKeys(..),我找到了一种发现表主键的方法; 然而,我无法找到桌子的独特结构,互联网也无法帮助我,因此我在这里结束提问:)

有没有一种干净的方法可以找到一个表的唯一约束(或者,更确切地说,对于一个表来说,列的名称必须是唯一的..嗯,你明白了,呵呵)呢? 致以最良好的祝愿


Nils

您可以查询数据字典:

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

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

找到关于约束的信息。唯一约束通常由索引强制执行。也许可以使用
DatabaseMetaData.getIndexInfo()
查找非唯一性为false的索引?

由于大多数数据库将这些约束存储为索引,因此可以使用前面提到的方法。在使用Postgresql时,这对我很有效

只需调用
getIndexInfo()
,将第四个参数设置为
true
,这一点很重要,正如文档所述:

unique
-如果为true,则仅返回唯一值的索引;如果错误, 返回索引,无论是否唯一

使用以下代码:

// 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());
}

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

谢谢Vincent,这正是我想要的!!非常感谢你!因此,我推测您不希望有Oracle特定的解决方案?是的,Oracle会在唯一约束中标识的任何列上创建唯一索引-这就是它强制唯一性的方式。但是,唯一索引可能完全以Oracle为中心。如果需要一个通用的解决方案,这可能并非在所有情况下都是正确的。而且,我认为Oracle还可以使用非唯一索引来强制实施唯一约束。
getUniqueConstraints(conn, "public", tableName);