【问题标题】:getIndexInfo returning wrong unique columns for composite primary keysgetIndexInfo 为复合主键返回错误的唯一列
【发布时间】:2019-02-03 03:43:04
【问题描述】:

我正在使用 JDBC,并且我使用 postgresql 创建了一个简单的表:

create table bank (
    bank_id int,
    bank_name varchar(40),
    bank_address varchar(80),
    user_id int,
    user_first_name varchar(40),
    user_surname varchar(40),
    user_phone varchar(12),
    primary key(bank_id, user_id)
);

问题是,当我检查 bank_id 是否唯一时,我得到了 true(当我期待 false 时,ofc)。这是我的函数的代码,用于检查表中的列是否唯一:

private static boolean checkIfUnique(Connection conn, String tableName,
    String columnName) {

    try {
        DatabaseMetaData meta = conn.getMetaData();
        ResultSet rs = meta.getIndexInfo(null, null, tableName, true, true);

        while(rs.next()) {
            if (rs.getString(9).equals(columnName)) {
                return true;
            }
        }

        return false;

    } catch (Exception e) {

        System.err.println("Exception: " + e + "\n" + e.getMessage());
    }

    return false;
}  

我不确定我做错了什么。任何建议都会有所帮助。谢谢。

【问题讨论】:

  • 不相关,但是:您应该确保在完成后关闭 ResultSet(在 finally 块中)。
  • @a_horse_with_no_name 或使用 try-with-resources
  • 感谢您的帮助。这完美地工作。出于好奇,未关闭的 ResultSet 对象会发生什么?

标签: java database postgresql jdbc


【解决方案1】:

getIndexInfo() 为每一列和索引返回一行。并且这两列都是主键的一部分,因此您会在 ResultSet 中获得两行,每列一个。

如果您想“单独”检查一列是否唯一,您还需要计算每个索引返回的行数getIndexInfo()

在您的情况下,ResultSet 看起来像这样:

TABLE_NAME  | INDEX_NAME  | COLUMN_NAME
------------+-------------+------------
bank        | bank_pkey   | bank_id
bank        | bank_pkey   | user_id

请注意,该结果中可能有更多唯一索引!

如果 bank_id 上存在唯一索引,您将拥有如下内容:

TABLE_NAME  | INDEX_NAME  | COLUMN_NAME
------------+-------------+------------
bank        | idx_bank_id | bank_id

只有这样,该列才会是唯一的。

因此,在循环中,您还需要计算要检查的列参与的列数每个索引。只有当该索引中的列总数为 1 时,您才能说该列是唯一的。

【讨论】:

    猜你喜欢
    • 2012-01-27
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多