В файле jtds.jar возвращена неверная дата - PullRequest
8 голосов
/ 20 января 2012

У меня есть таблица на MS SQL Server со столбцом с типом данных в качестве даты.Я использую jtds.jar для соединения JDBC с БД.Я беру DatabaseMetaData из подключения.Проверяя столбцы из DatabaseMetaData, я заметил, что

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

возвращает тип столбца как java.sql.Types.VARCHAR, который является строкой, а не датой.но он также возвращает

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

имя типа в качестве даты.

Но для Oracle возвращается тип данных даты как java.sql.Types.DATE.

Почему такая разница?

Ответы [ 2 ]

4 голосов
/ 14 января 2013

Это известная ошибка JTDS, см. http://sourceforge.net/p/jtds/bugs/679/.

Возвращенный тип данных для типа даты SQLServer возвращается как varchar с длиной 10. Это неправильно, он должен возвращаться как Sql.Date. int iType = rsMeta.getInt ("DATA_TYPE"); String tmp = rsMeta.getString ( "TYPE_NAME");

1 голос
/ 05 мая 2016

Это все еще остается открытой проблемой с 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

Это не идеально, но оно должно работать для других с подобной проблемой.

...