2012-01-20 16 views
7

Ho una tabella su MS SQL Server con una colonna che ha il tipo di dati come data. Sto usando jtds.jar per la connessione JDBC con DB. Sto prendendo DatabaseMetaData da Connection. Durante il controllo le colonne da DatabaseMetaData, ho osservato cheTipo di dati errato restituito per data in jtds.jar

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

rendimenti tipo di colonna come java.sql.Types.VARCHAR, che è una data stringa e non. ma restituisce anche

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

tipo nome come data.

Ma per Oracle, restituisce il tipo di dati data come java.sql.Types.DATE.

Perché questa differenza?

+0

perché non usare semplicemente '.getTimestamp (" DATA_TYPE ")' – epoch

+0

Come da mia conoscenza getInt ("DATA_TYPE") deve restituire uno dei tipi da http://docs.oracle.com/javase/1.4 .2/docs/api/constant-values.html # java.sql.Types.DATE – FlyingDutchman

+2

Ho trovato anche link simili: http://stackoverflow.com/questions/7885459/jdbc-jtds-bug-for-columns- of-type-date-and-timex – FlyingDutchman

risposta

4

Questo è un bug JTDS noto, vedere http://sourceforge.net/p/jtds/bugs/679/.

Il tipo di dati restituito per un tipo SQLServer Data viene restituito come varchar con una lunghezza di 10. Questo è sbagliato, deve restituire come Sql.Date. int iType = rsMeta.getInt ("DATA_TYPE"); String tmp = rsMeta.getString ("TYPE_NAME");

1

Questo sembra ancora essere un problema aperto con jTDS 1.3.1. Sono stato in grado di lavorare intorno ad esso tramite una query nel catalogo tabella di SQL Server direttamente per le tabelle con cui sto lavorando, e ottenere un elenco di colonne di data per la tavola:

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

Una volta che avete questa lista, è possibile esplicitamente controllare e vedere se la colonna è un tipo di data:

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

Quindi, dire che ho una tabella di esempio con tre colonne:

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

Questo codice stamperà i seguenti valori quando viene eseguito 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 

Non è l'ideale, ma dovrebbe funzionare per gli altri con un problema simile.

Problemi correlati