Как установить значения привязки в NULL с помощью драйвера JDBC jaybird от Firebird?

Я сталкиваюсь с небольшой ситуацией в крайних случаях при привязке null к PreparedStatement с помощью JDBC-драйвера Firebird jaybird. Вот пример заявления:

Class.forName("org.firebirdsql.jdbc.FBDriver");

// Observe the "local" in the connection string!
Connection con = DriverManager.getConnection(
    "jdbc:firebirdsql:local:C:/data/firebird/test.db", "TEST", "TEST");

// With this connection, I'm not able to reproduce the issue:
Connection con1 = DriverManager.getConnection(
    "jdbc:firebirdsql:localhost:C:/data/firebird/test.db", "TEST", "TEST");

PreparedStatement stmt = con.prepareStatement(
  "SELECT cast(? as varchar(1)) FROM rdb$database");
stmt.setObject(1, null);
ResultSet rs = stmt.executeQuery();
rs.next();
System.out.println(rs.getString(1));
System.out.println(rs.wasNull());

Вывод вышеуказанной программы

>
> false

Первая строка представляет собой пустую строку. Это действительно должно быть

> null
> true

Изменение этой строки...

stmt.setObject(1, null);

...в любую из этих строк...

stmt.setString(1, null);
stmt.setNull(1, Types.VARCHAR);

... тоже не помогает. Обходной путь заключается в том, чтобы встроить литералы null в операторы SQL вместо их привязки к подготовленному оператору. Что мне не хватает?

Подробности:

  • База данных: Firebird WI-V2.5.1.26351
  • Драйвер JDBC: jaybird-2.2.0
  • Java-версия: JDK 1.6.0_24
  • ОС: Windows 7 x64
  • Строка подключения JDBC: см. выше.

person Lukas Eder    schedule 24.08.2012    source источник
comment
Поскольку приведенный ниже ответ (и моя собственная попытка воспроизвести) показывают, что Jaybird работает так, как ожидалось, было бы неплохо включить дополнительную информацию: полную версию Firebird, версию Java, платформу ОС и используемую строку подключения JDBC (или если вы используете DataSource: его полный набор свойств). Если у вас есть рабочая программа воспроизведения и база данных, вы также можете подать заявку на tracker.firebirdsql.org, и я посмотрю   -  person Mark Rotteveel    schedule 25.08.2012
comment
@MarkRotteveel: Спасибо за ваши подсказки. Как получить полную версию Firebird? Я не знаю, как использовать Service API, тогда как rdb$get_context('SYSTEM', 'ENGINE_VERSION') возвращает 2.5.1. Остальная информация добавлена ​​в вопрос   -  person Lukas Eder    schedule 25.08.2012
comment
DatabaseMetaData.getDatabaseProductVersion() должен вернуть полную версию   -  person Mark Rotteveel    schedule 25.08.2012
comment
Хорошо, но я могу сузить круг до использования строки подключения. Я обновлю вопрос соответственно   -  person Lukas Eder    schedule 25.08.2012
comment
Похоже на баг в родной части. Есть ли конкретная причина, по которой вам нужен драйвер типа 2 (собственный)?   -  person Mark Rotteveel    schedule 25.08.2012
comment
Нет особой причины, я могу легко переключиться на другой тип URL. Я запускаю интеграционные тесты для предстоящей интеграции jOOQ с Firebird. Это был первый URL-адрес подключения, который я попробовал, и он сработал... Должен ли я подать заявку на эту проблему?   -  person Lukas Eder    schedule 25.08.2012
comment
Я уже создал тикет: tracker.firebirdsql.org/browse/JDBC-271   -  person Mark Rotteveel    schedule 25.08.2012


Ответы (2)


Я не могу воспроизвести проблему в Jaybird 2.2.0 и Firebird 2.1.3 (32-разрядная версия) в Windows 7 x64. Скопируйте исходный код и запустите его, чтобы получить ожидаемый результат.

Скриншот прикрепил на всякий случай:

введите здесь описание изображения

ОБНОВЛЕНИЕ

Протестировано на Jaybird 2.2.0 и Firebird 2.5.1 (32-разрядная) в Windows XP, по-прежнему не удается воспроизвести проблему -> Точно такой же вывод, как ожидал.

person tschan    schedule 24.08.2012
comment
Протестировано на jaybird 2.2.0 и firebird 2.5.1 (32-разрядная версия) в Windows XP, по-прежнему не удается воспроизвести проблему -> Точно такой же результат, как и ожидалось. - person tschan; 24.08.2012
comment
Спасибо за вашу помощь. Судя по всему, это ошибка драйвера JDBC: tracker.firebirdsql.org/browse/JDBC-271 - person Lukas Eder; 25.08.2012

Судя по всему, это ошибка в драйвере JDBC:

http://tracker.firebirdsql.org/browse/JDBC-271

Он появляется только при использовании такого URL-адреса подключения:

// Observe the "local" in the connection string!
Connection con = DriverManager.getConnection(
    "jdbc:firebirdsql:local:C:/data/firebird/test.db", "TEST", "TEST");

Не с этим сортом:

// With this connection, I'm not able to reproduce the issue:
Connection con1 = DriverManager.getConnection(
    "jdbc:firebirdsql:localhost:C:/data/firebird/test.db", "TEST", "TEST");
person Lukas Eder    schedule 25.08.2012
comment
Это также происходит с jdbc:firebirdsql:native://localhost/D:/data/DB/testdatabase.fdb. - person Mark Rotteveel; 25.08.2012
comment
Похоже, это проблема только тогда, когда параметр является частью списка столбцов select, он правильно работает как null, когда он является частью where-условия или insert-оператора и т. д. - person Mark Rotteveel; 25.08.2012
comment
@MarkRotteveel: мои интеграционные тесты указывают на другое. Проблема действительно связана с операцией CAST(? as xxx). Если CAST используется в операторах INSERT или UPDATE, аналогичные проблемы возникают с любым типом данных. Я также прокомментировал это в JDBC-271. - person Lukas Eder; 25.08.2012
comment
Ошибка будет исправлена ​​в Jaybird 2.2.1 и 2.3. - person Mark Rotteveel; 02.09.2012