Derby 对 NULL 值的处理

Luk*_*der 5 sql db2 null derby strong-typing

我是 Derby 的新手,我注意到就null值而言,我面临着与使用 DB2 RDBMS 类似的问题。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
Run Code Online (Sandbox Code Playgroud)

这也不是(这实际上是 jOOQ 所做的):

insert into T_AUTHOR (
  ID, FIRST_NAME, LAST_NAME, 
  DATE_OF_BIRTH, YEAR_OF_BIRTH, ADDRESS) 
select ?, ?, ?, ?, ?, ? 
from SYSIBM.SYSDUMMY1
Run Code Online (Sandbox Code Playgroud)

因为这两个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
Run Code Online (Sandbox Code Playgroud)

或者像这样分别

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
Run Code Online (Sandbox Code Playgroud)

null但在 Java 中,通常应该转换为的类型是未知的:

  • 在此示例中,类型可以从 insert 子句派生,但这对于更一般的用例来说可能会很复杂或不可能。
  • 在其他示例中,我可以选择任何类型进行强制转换(例如始终强制转换为int),但这在本例中不起作用,因为您无法将cast(null as int)值放入ADDRESS
  • 使用 HSQLDB(这个问题的另一个候选者),我可以简单地编写cast(null as object)在大多数情况下都有效的代码。但德比没有object类型。

这个问题之前一直困扰着我使用DB2,至今还没有找到解决方案。有谁知道针对这些 RDBMS 中的任何一个此问题的稳定通用的解决方案吗?

  • 德比
  • 数据库2

Ian*_*vde 4

如果在 INSERT 上使用 VALUES 子句,则不必强制转换 NULL 值:

insert into T_AUTHOR (
  ID, FIRST_NAME, LAST_NAME, 
  DATE_OF_BIRTH, YEAR_OF_BIRTH, ADDRESS) 
VALUES ( 
  1000, 'Lukas', 'Eder', 
  '1981-07-10', null, null 
);
Run Code Online (Sandbox Code Playgroud)

这将像您期望的那样工作(即数据库可以确定 NULL 对应于整数和 varchar(500)。这适用于 DB2 和 Derby(并且也应该适用于几乎任何其他数据库引擎)。

您也可以将 VALUES 与参数标记一起使用,而无需对其进行 CAST。

发出语句时必须进行转换的原因insert into ... select from是因为 SELECT 部分优先 - select 语句返回某些数据类型,无论它们是否与您尝试将其插入的表兼容。如果它们不兼容,您将收到错误(使用强类型数据库引擎,例如 DB2 <= 9.5),或者引擎将执行隐式类型转换(如果可能)。