java - 为什么 IS_AUTOINCREMENT 元数据列根据 MS SQL Server 的类型返回不一致的值?

标签 java resultset jtds

我正在尝试从数据库连接动态获取数据库架构信息,但遇到了一个奇怪的问题。我不确定这在结果集中是如何发生的,但它只发生在 MS SQL Server 上。当我使用 ResultSet.getString() 请求时,"IS_AUTOINCRMENT" 列值会被正确检索为 "YES"。但是,当我使用 Request.getBoolean() 请求它时,它会错误地为自动增量列返回 FALSE

public Collection<DBTable> getTables() {
    HashSet<DBTable> tables = new HashSet<>();
    try {
        ResultSet rs = this.conn().getMetaData().getTables(this.conn().getCatalog(), null, null, new String[] { "TABLE" });
        while (rs.next()) {
            String catalog = rs.getString("TABLE_CAT");
            String schema = rs.getString("TABLE_SCHEM"); 
            String name = rs.getString("TABLE_NAME");
            DBTable table = new DBTable(catalog, schema, name);
            ResultSet columns = this.conn().getMetaData().getColumns(catalog, schema, name, null);
            while (columns.next()) {
                String columnName = columns.getString("COLUMN_NAME");
                int dataType = columns.getInt("DATA_TYPE"); // from java.sql.Types
                String typeName = columns.getString("TYPE_NAME");
                int columnSize = columns.getInt("COLUMN_SIZE");
                boolean isNullable = columns.getBoolean("IS_NULLABLE");
                boolean isAutoIncrement = columns.getBoolean("IS_AUTOINCREMENT");
                String autoIncString = columns.getString("IS_AUTOINCREMENT");
                if (autoIncString.equals("YES") && !isAutoIncrement)
                    throw new IllegalStateException("Why is string YES but boolean FALSE?");
                table.addColumn(new DBColumn(columnName, dataType, typeName, columnSize, isNullable, isAutoIncrement));
            }
            columns.close();
            tables.add(table);
        }
        rs.close();
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return tables;
}

在此示例代码中,当 MS SQL 处理自动增量字段时,会引发 IllegalStateException,但 MySQL 中不会引发该异常。我对 SQL Server 使用 JTDS v1.3.1,对 MySQL 使用connector/j 5.1.27。我什至不确定这怎么会在 ResultSet 中发生。

我添加了一些代码来循环遍历(ResultSet)以检查数据类型:

for (int x = 1; x <= columns.getMetaData().getColumnCount(); x++)
    System.out.println(x + ": " + columns.getMetaData().getColumnName(x)+ " (" + columns.getMetaData().getColumnType(x) + ")");

这将验证对于 MySQL 和 MS SQL,“IS_AUTOINCRMENT” 列返回为字符串(来自 java.sql.Types 的数据类型 1)。所以我觉得我的解决方案只是将其与 "YES" 进行比较以使其成立。但我仍然想了解这里发生了什么。有什么想法吗?

最佳答案

我猜想在较低的级别上,"is"答案是作为字符串输入的——而不是 boolean 值。然后它会以字符串的形式返回给您。

对于元数据查询来说,这种事情并非闻所未闻,它们通常以时髦的方式组合在 JDBC 驱动程序中,并且取决于底层数据库必须以系统表的方式提供什么。

将真值类型的答案格式化为字符串可能更容易(在最小公分母的基础上),特别是因为“boolean ”支持和兼容性在数据库之间变化很大。

Java 规范还规定,所有这些都应以字符串形式返回。

参见: -http://docs.oracle.com/javase/6/docs/api/java/sql/DatabaseMetaData.html#getColumns(java.lang.String,%20java.lang.String,%20java.lang.String,%20java.lang.String)

长话短说——事情就是这样,只要顺其自然。有一点需要注意:我个人不会依赖于答案的具体情况。

关于java - 为什么 IS_AUTOINCREMENT 元数据列根据 MS SQL Server 的类型返回不一致的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20028108/

相关文章:

java - Java 中的多项式微积分库?

java - 如果 java 应用程序的结果集没有被关闭,这意味着什么?

Java GSS/JDBC 问题

java - Jre 1.8.66 上的 jtds ArrayIndexOutOfBoundsException

java - 我可以在后台迭代吗?

java - AOSP 方法名称结尾

java结果集覆盖

java - resultset.getTimestamp 和 ThreadLocal 警告 Java

java.lang.ClassNotFoundException : net. sourceforge.jtds.jdbc.Drive

java - Android RecyclerView Adapter 在单元测试中给出 null