我是Derby的新手,我注意到,就使用DB2 RDBMS而言,我遇到的问题与null值有关. Derby文档声明,null值必须具有与之关联的类型(DB2最终在版本9.7中除外):
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,ADDRESS) select ?,?,? from SYSIBM.SYSDUMMY1
因为两个空值没有与之关联的类型.解决方案是写这样的东西:
insert into T_AUTHOR ( ID,cast(null as int),cast(null as varchar(500)) from SYSIBM.SYSDUMMY1
或者像这样,分别
insert into T_AUTHOR ( ID,ADDRESS) select ?,cast(? as int),cast(? as varchar(500)) from SYSIBM.SYSDUMMY1
但是在Java中,经常应该转换为null的类型是未知的:
>在此示例中,类型可以从insert子句派生,但对于更一般的用例,这可能被证明是复杂的或不可能的.
>在其他示例中,我可以选择任何类型的转换(例如总是转换为int),但这在本示例中不起作用,因为您不能将转换(null作为int)值放入ADDRESS.
>使用HsqlDB(此问题的另一个候选者),我可以简单地编写cast(null作为对象),这在大多数情况下都可以使用.但是Derby没有对象类型.
以前这个问题一直困扰着我,我还没有找到解决方案.对于任何这些RDBMS,有谁知道这个问题的稳定,通用的解决方案?
>德比
> DB2
解决方法
如果在INSERT上使用VALUES子句,则不必转换NULL值:
insert into T_AUTHOR ( ID,ADDRESS) VALUES ( 1000,null );
这将按预期工作(即数据库可以确定NULL对应于整数和varchar(500).这适用于DB2和Derby(并且应该在几乎任何其他数据库引擎中工作).
您也可以将VALUES与参数标记一起使用,而无需对它们进行CAST.
将insert插入… select from语句时必须进行强制转换的原因是SELECT部分优先 – select语句返回某些数据类型,无论它们是否与您尝试插入的表兼容他们进去了.如果它们不兼容,您将收到错误(使用强类型数据库引擎,如DB2< = 9.5)或引擎将执行隐式类型转换(如果可能).