jtds.jar 中的日期返回错误的数据类型

发布于 2024-12-27 18:41:38 字数 423 浏览 4 评论 0原文

我在 MS SQL Server 上有一个表,其中有一列的数据类型为日期。我正在使用 jtds.jar 与 DB 进行 JDBC 连接。我正在从 Connection 获取 DatabaseMetaData。在检查 DatabaseMetaData 中的列时,我观察到

int iType = rsMeta.getInt("DATA_TYPE");

返回的列类型为 java.sql.Types.VARCHAR,它是字符串而不是日期。但它也返回

String tmp = rsMeta.getString("TYPE_NAME");

类型名称作为日期。

但对于 Oracle,它返回日期数据类型为 java.sql.Types.DATE。

为什么会有这样的差异呢?

I have a table on MS SQL Server with a column having data type as date. I am using jtds.jar for JDBC connection with DB. I am taking DatabaseMetaData from Connection. While checking columns from DatabaseMetaData, I observed that

int iType = rsMeta.getInt("DATA_TYPE");

returns Column type as java.sql.Types.VARCHAR which is a string and not date. but it also returns

String tmp = rsMeta.getString("TYPE_NAME");

type name as date.

But for Oracle, It returns the date datatype as java.sql.Types.DATE.

Why is such a difference?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

残龙傲雪 2025-01-03 18:41:38

这是一个已知的 JTDS 错误,请参阅 http://sourceforge.net/p/jtds/bugs/ 679/

SQLServer 日期类型的返回数据类型作为
长度为 10 的 varchar。这是错误的,它应该返回为
Sql.日期。 int iType = rsMeta.getInt("DATA_TYPE");字符串 tmp =
rsMeta.getString("TYPE_NAME");

This is a known JTDS bug, see http://sourceforge.net/p/jtds/bugs/679/.

The returned datatype for a SQLServer Date type is returned as a
varchar with a length of 10. This is wrong, it should return as
Sql.Date. int iType = rsMeta.getInt("DATA_TYPE"); String tmp =
rsMeta.getString("TYPE_NAME");

忆梦 2025-01-03 18:41:38

对于 jTDS 1.3.1,这似乎仍然是一个悬而未决的问题。我可以通过直接查询 SQL Server 表目录来查找我正在使用的表,并获取该表的日期列列表来解决此问题:

private HashMap<String,Boolean> getDateColumns (String tableName, String schemaName, Connection conn) throws Exception {
    String sql = "SELECT table_name + ',' + column_name" 
                + " FROM  INFORMATION_SCHEMA.COLUMNS " 
                + " WHERE TABLE_SCHEMA = N'" + schemaName + "' "
                + " AND   table_name = N'" + tableName + "' " 
                + " AND data_type IN ('date', 'datetime', 'datetime2')";

    Statement stmt = conn.createStatement();                        
    ResultSet rs = stmt.executeQuery(sql);
    HashMap<String,Boolean> dateCols = new HashMap<String,Boolean>();

    while (rs.next()) {
        String tableColKey = rs.getString(1);           
        dateCols.put(tableColKey.toUpperCase(), true );
    }

    rs.close();     
    return dateCols;        
}

一旦获得此列表,您可以显式检查并查看该列是否是日期类型:

private ResultSetMetaData getTableMetaData (String tableName, Connection conn) throws Exception {
    String sql = "SELECT * FROM dbo." + tableName + " where 1 = 2 ";
    Statement stmt = conn.createStatement();                        
    ResultSet rs = stmt.executeQuery(sql);
    ResultSetMetaData rsmd = rs.getMetaData();
    rs.close();

    HashMap<String,Boolean> dateColumns =  getDateColumns (tableName, conn); 

    for (int i = 1; i <= rsmd.getColumnCount(); i++) {                

        String key = tableName + "," + rsmd.getColumnName(i);
        int type = -1;
        if (dateColumns.containsKey(key)) {
            type = Types.DATE;
        }
        else {
            type = rsmd.getColumnType(i);
        }

        System.out.println ("... col: " + rsmd.getColumnName(i) + ", driver type name: " + rsmd.getColumnTypeName(i) + ", driver type: " + rsmd.getColumnType(i) + ", final data type: " + type);
    }       

    return rsmd;
}

因此,假设我有一个包含三列的示例表:

SAMPLE
------------------
SITE_ID     numeric
START_DATE  date
END_DATE    date

当使用 jTDS 运行时,此代码将打印以下值:

... col: SITE_ID, driver type name: numeric, driver type: 2, final data type: 2
... col: START_DATE, driver type name: nvarchar, driver type: 12, final data type: 91
... col: END_DATE, driver type name: nvarchar, driver type: 12, final data type: 91

这并不理想,但它应该适用于其他有类似问题的人。

This still appears to be an open issue with jTDS 1.3.1. I was able to work around it by querying the SQL Server table catalog directly for the tables I'm working with, and getting a list of date columns for the table:

private HashMap<String,Boolean> getDateColumns (String tableName, String schemaName, Connection conn) throws Exception {
    String sql = "SELECT table_name + ',' + column_name" 
                + " FROM  INFORMATION_SCHEMA.COLUMNS " 
                + " WHERE TABLE_SCHEMA = N'" + schemaName + "' "
                + " AND   table_name = N'" + tableName + "' " 
                + " AND data_type IN ('date', 'datetime', 'datetime2')";

    Statement stmt = conn.createStatement();                        
    ResultSet rs = stmt.executeQuery(sql);
    HashMap<String,Boolean> dateCols = new HashMap<String,Boolean>();

    while (rs.next()) {
        String tableColKey = rs.getString(1);           
        dateCols.put(tableColKey.toUpperCase(), true );
    }

    rs.close();     
    return dateCols;        
}

Once you have this list, you can explicitly check and see if the column is a date type:

private ResultSetMetaData getTableMetaData (String tableName, Connection conn) throws Exception {
    String sql = "SELECT * FROM dbo." + tableName + " where 1 = 2 ";
    Statement stmt = conn.createStatement();                        
    ResultSet rs = stmt.executeQuery(sql);
    ResultSetMetaData rsmd = rs.getMetaData();
    rs.close();

    HashMap<String,Boolean> dateColumns =  getDateColumns (tableName, conn); 

    for (int i = 1; i <= rsmd.getColumnCount(); i++) {                

        String key = tableName + "," + rsmd.getColumnName(i);
        int type = -1;
        if (dateColumns.containsKey(key)) {
            type = Types.DATE;
        }
        else {
            type = rsmd.getColumnType(i);
        }

        System.out.println ("... col: " + rsmd.getColumnName(i) + ", driver type name: " + rsmd.getColumnTypeName(i) + ", driver type: " + rsmd.getColumnType(i) + ", final data type: " + type);
    }       

    return rsmd;
}

So, say I have a sample table with three columns:

SAMPLE
------------------
SITE_ID     numeric
START_DATE  date
END_DATE    date

This code will print the following values when run with jTDS:

... col: SITE_ID, driver type name: numeric, driver type: 2, final data type: 2
... col: START_DATE, driver type name: nvarchar, driver type: 12, final data type: 91
... col: END_DATE, driver type name: nvarchar, driver type: 12, final data type: 91

It's not ideal, but it should work for others with a similar problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文