2012-01-20 18 views
7

Tengo una tabla en MS SQL Server con una columna que tiene el tipo de datos como fecha. Estoy utilizando jtds.jar para la conexión JDBC con DB. Estoy tomando DatabaseMetaData de Connection. Mientras que el registro de columnas DatabaseMetaData, he observado queTipo de datos incorrectos devueltos para la fecha en jtds.jar

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

vuelve Tipo de columna como java.sql.Types.VARCHAR que es una cadena y no la fecha. pero también devuelve

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

tipo nombre como fecha.

Pero para Oracle, Devuelve el tipo de datos de fecha como java.sql.Types.DATE.

¿Por qué es tal la diferencia?

+0

¿por qué no utiliza '.getTimestamp (" DATA_TYPE ")' – epoch

+0

Según mi conocimiento, getInt ("DATA_TYPE") debe devolver uno de los tipos de http://docs.oracle.com/javase/1.4 .2/docs/api/constant-values.html # java.sql.Types.DATE – FlyingDutchman

+2

También encontré un enlace similar: http://stackoverflow.com/questions/7885459/jdbc-jtds-bug-for-columns- of-type-date-and-timex – FlyingDutchman

Respuesta

4

Este es un error conocido de JTDS, vea http://sourceforge.net/p/jtds/bugs/679/.

El tipo de datos devueltos para un tipo SQL Server fecha se devuelve como un varchar con una longitud de 10. Esto es incorrecto, debe devolver como Sql.Date. int iType = rsMeta.getInt ("DATA_TYPE"); String tmp = rsMeta.getString ("TYPE_NAME");

1

Esto todavía parece ser un problema abierto con jTDS 1.3.1. Yo era capaz de trabajar alrededor de él mediante la consulta del catálogo de tabla de SQL Server directamente para las tablas con los que trabajo, y conseguir una lista de las columnas de fecha para la tabla:

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;   
} 

vez que tenga esta lista, puede comprobar explícitamente y ver si la columna es un tipo de fecha:

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; 
} 

Por lo tanto, decir que tengo una tabla de ejemplo con tres columnas:

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

Este código imprimirá los siguientes valores cuando se ejecuta con jT DS:

... 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 

No es ideal, pero debería funcionar para otros con un problema similar.

Cuestiones relacionadas