Как указать нулевое значение в MS Access через мост JDBC-ODBC? - PullRequest
4 голосов
/ 11 июня 2010

Я не могу вызвать setNull для PreparedStatement с помощью MS Access (sun.jdbc.odbc.JdbcOdbcDriver)

preparedStatement.setNull(index, sqltype). 

Есть ли обходной путь для этого?Для LONGBINARY типа данных я пробовал следующие вызовы, ни один не работал.

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)

Ответы [ 3 ]

5 голосов
/ 31 октября 2013

Ответ, который я наблюдал , чтобы работать "достаточно хорошо" для связывания null с большинством типов данных с JDBC 4.1, Java 7, MS Access 2013 и мостом JDBC-ODBC, таков,который я встроил в 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;
}
3 голосов
/ 31 октября 2013

Я только что проверил это и для поля OLE Object (LONGBINARY) в базе данных Access 2010 я обнаружил, что все пять из этих вариантов позволяют мне указывать нулевое значение в качестве параметра для PreparedStatement с использованием ванильного JDBC / ODBCDriver={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);

Особенно интересно, что

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

работает не , учитывая, что при извлечении OLE Object из базы данных Access java.sql.Types.LONGVARBINARY в соответствии с 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));

, который возвращает:

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

Статья в Википедии о ODBC включает history , свидетельствующая о том, что после того, как более ранние усилия ("SQL / CLI") стали частью стандарта ISO SQL, Microsoft по сути разветвила свою собственную версию и в конце концов предложила ODBC.Если это так, то ранние попытки соответствовать «стандарту ODBC», возможно, столкнулись с теми же трудностями, что и попытки соответствовать «стандарту» документа RTF от Microsoft: «стандартом» было то, что Microsoft реализовала и подчиняласьизменить по собственному усмотрению Microsoft.

Однако в официальном документе Microsoft ODBC 1995 года, доступном по ссылке для скачивания здесь , последовательно указывается тип данных "OLE Object" как отображение на "* BINARY" или«необработанные» типы (или, в случае с SQL Server, к устаревшему типу данных IMAGE).Таким образом, несоответствие CHAR / BINARY, похоже, не является случаем некоторой ранней причуды ODBC, которая только что увековечилась.

Конечно, эта загадка не нова.В ветке форума здесь от ~ 11 лет назад предполагается, что эта проблема возникла, когда что-то изменилось после выпуска JDK 1.4.

И, наконец, Oracle заявила, что мост JDBC-ODBC "будетудалено в JDK 8 "(ссылка: здесь ).Так что, если не было «официального» объяснения (или исправления, в этом отношении), становится все менее вероятным, что какое-либо будет предстоящее.

1 голос
/ 23 июня 2011

Однажды я увидел похожую ошибку, когда отправлял запрос SQL с двумя условиями в предложении where. Одно из условий необходимо было процитировать. Это был номер в формате varchar. MSSQL-сервер требовал, чтобы условие было заключено в кавычки, иначе я увидел ошибку, возникшую в вашем вопросе.

...