ms-access jdbc odbc blob jdbc-odbc

¿Cómo especificar el valor nulo en MS Access a través del puente JDBC-ODBC?



ms-access blob (3)

No puedo llamar a setNull en PreparedStatement utilizando MS Access (sun.jdbc.odbc.JdbcOdbcDriver)

preparedStatement.setNull(index, sqltype).

¿Hay una solución para esto? Para el tipo de datos LONGBINARY , probé las siguientes llamadas, ninguna de las dos funcionó.

setNull(index, java.sql.Types.VARBINARY) setNull(index, java.sql.Types.BINARY)

java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver]Invalid SQL data type at sun.jdbc.odbc.JdbcOdbc.createSQLException(JdbcOdbc.java:6957) at sun.jdbc.odbc.JdbcOdbc.standardError(JdbcOdbc.java:7114) at sun.jdbc.odbc.JdbcOdbc.SQLBindInParameterNull(JdbcOdbc.java:986) at sun.jdbc.odbc.JdbcOdbcPreparedStatement.setNull(JdbcOdbcPreparedStatement.java:363)


Vi una vez un error similar cuando estaba enviando una consulta SQL con 2 condiciones en la cláusula where. Una de las condiciones necesarias para ser citada. Era un número en formato varchar. El servidor MSSQL requirió que se citara la condición o si no vi el error que recibió en su pregunta.


La respuesta que he observado que funciona "bastante bien" para enlazar null a la mayoría de los tipos de datos con JDBC 4.1, Java 7, MS Access 2013 y el puente JDBC-ODBC es esta, que incorporé a jOOQ :

switch (sqlType) { case Types.BINARY: case Types.VARBINARY: case Types.LONGVARBINARY: case Types.BLOB: stmt.setNull(nextIndex(), Types.VARCHAR); break; default: stmt.setString(nextIndex(), null); break; }


Acabo de probar esto y para un campo OLE Object ( LONGBINARY ) en una base de datos de Access 2010 encontré que las cinco variaciones me permitieron especificar un valor nulo como parámetro para PreparedStatement usando vanil JDBC / ODBC Driver={Microsoft Access Driver (*.mdb, *.accdb)} :

s.setNull(4, java.sql.Types.LONGNVARCHAR); s.setNull(4, java.sql.Types.LONGVARCHAR); s.setNull(4, java.sql.Types.NCHAR); s.setNull(4, java.sql.Types.NVARCHAR); s.setNull(4, java.sql.Types.VARCHAR);

Es particularmente interesante que

s.setNull(4, java.sql.Types.LONGVARBINARY);

no funciona, teniendo en cuenta que cuando recuperamos un OLE Object de una base de datos de Access lo que obtenemos es un java.sql.Types.LONGVARBINARY acuerdo con un objeto ResultSetMetaData :

String SQL; SQL = "SELECT Photo FROM City WHERE City_ID = 12"; s = conn.createStatement(); s.executeQuery(SQL); ResultSet rs = s.getResultSet(); ResultSetMetaData rsmd = rs.getMetaData(); String accessTypeName = rsmd.getColumnTypeName(1); int javaType = rsmd.getColumnType(1); String javaTypeName = ( javaType == java.sql.Types.LONGVARBINARY ? "java.sql.Types.LONGVARBINARY" : "some other Type" ); System.out.println(String.format("The database-specific type name for this column is ''%s''", accessTypeName)); System.out.println(String.format("The SQL type for this column is: %d (%s)", javaType, javaTypeName));

Eso vuelve:

The database-specific type name for this column is ''LONGBINARY'' The SQL type for this column is: -4 (java.sql.Types.LONGVARBINARY)

El artículo de Wikipedia sobre ODBC incluye una historia que sugiere que después de un esfuerzo anterior ("SQL / CLI") se convirtió en parte del estándar ISO SQL, Microsoft esencialmente bifurcó su propia versión y, finalmente, se le ocurrió ODBC. Si ese es el caso, los esfuerzos iniciales para cumplir con un estándar "ODBC" pueden haber enfrentado las mismas dificultades que aquellos que intentan ajustarse al "estándar" de documentos RTF de Microsoft: el "estándar" era cualquier cosa que Microsoft implementara y estuviera sujeto a cambiar a la entera discreción de Microsoft.

Sin embargo, el Libro Blanco ODBC de 1995 de Microsoft, disponible a través del enlace de descarga aquí , se refiere consistentemente al tipo de datos "Objeto OLE" como mapeo a tipos "* BINARY" o "raw" (o, en el caso de SQL Server, al now- tipo de datos IMAGE en desuso). Entonces, la discrepancia CHAR / BINARY no parece ser un caso de alguna peculiaridad temprana de ODBC que acaba de perpetuarse.

Ciertamente, este misterio no es nuevo. Un hilo del foro aquí desde hace ~ 11 años sugiere que este problema surgió cuando algo cambió después de que se lanzara JDK 1.4.

Y finalmente, Oracle ha declarado que el Puente JDBC-ODBC "se eliminará en JDK 8" (ref: aquí ). Entonces, si no ha habido una explicación "oficial" (o una solución, para el caso), cada vez es más improbable que se produzca alguna.