2015-06-06 2 views
0

У меня есть производственная база данных Oracle, и я использую HSQLDB 2.3 в качестве тестовой DB для интеграции, чтобы проверить некоторые методы DAO. Я заметил, что HSQL не очень хорошо справляется с датами и привязкой параметров к Java PreparedStatement. Например, запрос ниже работ, как и ожидалось, при условии, COLUMN2 тип дата:HSQLDB 2.3 и проблемы с привязкой параметров

select 
    column1, 
    column2 
from 
    table 
where 
    trunc(column2) = trunc(sysdate + 14) 
    and column3 = ? 

Но это другой вопрос просто не работает, когда я установил Int, preparedStatement.setInt(1, 14), на первый параметр (?). Излишне говорить, что он отлично работает в Oracle.

select 
    column1, 
    column2 
from 
    table 
where 
    trunc(column2) = trunc(sysdate + ?) 
    and column3 = ? 

Любопытно, что если вы пытаетесь что-то вроде select (sysdate + 14) future from any_single_row_table он работает, как ожидалось, но он показывает текущую дату, если вы пытаетесь select (sysdate + ?) future from any_single_row_table

Почему он ведет себя, как это? Является ли это ошибкой в ​​реализации готовой инструкции HSQL? Есть ли обходной путь?

+0

Еще один хороший пример, почему это плохая идея использовать различные СУБД для тестирования, чем вы использование в производстве. –

+0

В моем идеальном мире Oracle и все крупные игроки имели бы очень легкие базы данных «в памяти» для тестовых целей, поэтому у нас не было бы такого несоответствия. Но, к сожалению, это не относится к жестокому реальному миру, и мы должны упасть на эти субоптимальные решения, чтобы продолжать идти и поставлять качественные продукты. –

+0

Я не вижу необходимости в легкой базе данных в памяти для тестирования. Просто настройте сервер, на котором работает Oracle, и позвольте вашему модульному тесту подключиться к этому. Он может даже запускаться на вашем сервере CI - если вы не наложите на него большую нагрузку, Oracle фактически не потребует много ресурсов. Ваша текущая проблема - это только верхушка айсберга. –

ответ

0

Вы используете простую арифметику даты, которая относится к Oracle и в некоторой степени поддерживается HSQLDB. Вы можете попробовать явное значение INTERVAL, которое является стандартным SQL. Вы должны также использовать самую последнюю версию HSQLDB (в настоящее время 2.3.3 релиз-кандидата) как совместимость синтаксиса эволюционировала в каждой версии:

select 
    column1, 
    column2 
from 
    table 
where 
    trunc(column2) = trunc(sysdate + cast(? as interval day)) 
    and column3 = ? 
+0

Извините, но я не думаю, что это так, потому что, как сказано выше, операция с датой работает очень хорошо. Если я заменю параметр на int literal, он будет работать как шарм. Кажется, что-то связано с реализацией PreparedStatement, но, к сожалению, у меня пока не было возможности это подтвердить. Но я последую за вашим вторым советом и дам 2.3.3 шанс (в настоящее время я использую 2.3.2). –

+0

Существует большое различие между параметром (он не имеет типа) и литералом (у него есть тип). Определение типа параметра может быть неправильным и может быть принудительно выполнено с помощью CAST. – fredt

Смежные вопросы