我是Derby的新手,我注意到我面临类似的问题,因为在使用DB2 RDBMS时,直到涉及null
值。 Derby文档状态,即一个null
值必须有一个与之关联的类型(的东西,DB2终于得到了在9.7版本去掉):Derby处理NULL值
http://db.apache.org/derby/docs/10.7/ref/crefsqlj21305.html
现在,我试图找到一个一般解决方案在这里这个问题,因为这将是我的数据库抽象库jOOQ的一部分。下面的例子只是记录了这个问题。想想其他任何(更复杂的)例子。以下不工作:
insert into T_AUTHOR (
ID, FIRST_NAME, LAST_NAME,
DATE_OF_BIRTH, YEAR_OF_BIRTH, ADDRESS)
select
1000, 'Lukas', 'Eder',
'1981-07-10', null, null
from SYSIBM.SYSDUMMY1
也不做这个(这是实际上是由jOOQ完成):
insert into T_AUTHOR (
ID, FIRST_NAME, LAST_NAME,
DATE_OF_BIRTH, YEAR_OF_BIRTH, ADDRESS)
select ?, ?, ?, ?, ?, ?
from SYSIBM.SYSDUMMY1
因为两个null
值没有与之相关联的类型。该解决方案将是写是这样的:
insert into T_AUTHOR (
ID, FIRST_NAME, LAST_NAME,
DATE_OF_BIRTH, YEAR_OF_BIRTH, ADDRESS)
select
1000, 'Lukas', 'Eder',
'1981-07-10', cast(null as int), cast(null as varchar(500))
from SYSIBM.SYSDUMMY1
还是这个样子,分别
insert into T_AUTHOR (
ID, FIRST_NAME, LAST_NAME,
DATE_OF_BIRTH, YEAR_OF_BIRTH, ADDRESS)
select
?, ?, ?, ?, cast(? as int), cast(? as varchar(500))
from SYSIBM.SYSDUMMY1
但很多时候,在Java中,null
应该被强制转换为类型未知:
- 在这个例子中,类型可以从insert子句派生,但是对于更一般的用例来说,这可能证明是复杂或不可能的。
- 在其他示例中,我可以为演员选择任何类型(例如始终投射到
int
),但在此示例中不起作用,因为您无法将cast(null as int)
的值放入ADDRESS
。 - 有了HSQLDB(这个问题的另一个候选者),我可以简单地编写
cast(null as object)
,这在大多数情况下都可以工作。但德比没有object
类型。
以前这个问题一直让我讨厌DB2,我还没有找到解决方案。有谁知道稳定和一般解决这个问题的任何这些RDBMS?
- 德比
- DB2
感谢您输入Bryan。我不知道为什么我放弃绑定变量。当然,我的库总是使用绑定变量来提高性能/安全性等,而不是直接将值内联到SQL。我会修改这个问题。 – 2011-02-05 15:33:51
不用担心。您可能遇到https://issues.apache.org/jira/browse/DERBY-1938,这是刚刚修复的。你在使用最新的德比(10.7)吗?如果没有,请尝试一下,看看setObject(null)现在是否工作得更好。 – 2011-02-05 19:59:55
是的,我正在使用Derby 10.7.1.1。但实际上这是`setObject(null)`的一个好提示。我有两个错误的组合,首先``Connection.prepareStatement()`调用不接受`null`文字或'cast(?as integer)`表达式(如果整数是错误的类型)。当我简单地为空值准备`?`时,我的库调用`PreparedStatement.setNull(N,Object.class)`,这也没有工作。但`setObject(N,null)`似乎工作。我会仔细检查... – 2011-02-06 08:33:03