2015-06-06 22 views
0

我有一个生产Oracle数据库,我使用HSQLDB 2.3作为集成测试数据库来验证一些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支持。您可以尝试使用标准SQL的显式INTERVAL值。你也应该使用最新版本的HSQLDB(目前2.3.3发布候选)作为语法兼容已经演变为每个版本:

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

对不起,但我不认为是这样,因为如上所述,日期操作工作得很好。如果我用int文字替换参数,它会像魅力一样运行。这似乎与PreparedStatement实现有关,但不幸的是,我还没有机会确认。但是我会遵循你的第二条建议,并给2.3.3一个机会(目前我正在使用2.3.2)。 –

+0

参数(它没有类型)和文字(它有一个类型)之间有一个主要区别。参数类型的确定可能是错误的,可以用CAST强制进行。 – fredt