Hana DB 不允许在可空字段中使用空值

Posted

技术标签:

【中文标题】Hana DB 不允许在可空字段中使用空值【英文标题】:Hana DB is not allowing nulls in a nullable field 【发布时间】:2020-03-26 07:55:51 【问题描述】:

我的shema看起来像这样:

CREATE TABLE  newsletter_status(
    identificationnumber BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 0)  NOT NULL PRIMARY KEY,
    bpid varchar(10),
    consumer varchar(4) NOT NULL,
    source varchar(10),
    vkorg varchar(4) NOT NULL,
    cryptid varchar(255) NOT NULL,
    status varchar(25),
    regDat timestamp,
    confirmDat timestamp,
    updateDat timestamp
  );

CREATE TABLE  scpnewsletter (version varchar(255));

CREATE INDEX bpid_index ON newsletter_status (bpid);
CREATE INDEX cryptid_index ON newsletter_status (cryptid);

在 H2 数据库中本地运行,这适用于插入。插入一个对象,其中设置了字段 consumer、source、vkorg、cryptid 和 status,其他字段不设置。数据库应生成一个识别号。而H2确实

在使用 HANA 数据库的客户 DEV 环境中运行时,插入失败,说明:

PreparedStatementCallback; uncategorized SQLException for SQL [INSERT INTO newsletter_status (identificationnumber,bpid,consumer,source,vkorg,cryptid,status,regDat,confirmDat,updateDat) VALUES (?,?,?,?,?,?,?,?,?,?)]; SQL state [HY000]; error code [287]; SAP DBTech JDBC: [287]: cannot insert NULL or update to NULL: Not nullable "IDENTIFICATIONNUMBER" column; nested exception is com.sap.db.jdbc.exceptions.JDBCDriverException: SAP DBTech JDBC: [287]: cannot insert NULL or update to NULL: Not nullable "IDENTIFICATIONNUMBER" column  

它不喜欢Identificationnumber 为空。

走得更远。如果我添加一个标识号,它对 bpid 的描述与此相同:

PreparedStatementCallback; uncategorized SQLException for SQL [INSERT INTO newsletter_status (identificationnumber,bpid,consumer,source,vkorg,cryptid,status,regDat,confirmDat,updateDat) VALUES (?,?,?,?,?,?,?,?,?,?)]; SQL state [HY000]; error code [287]; SAP DBTech JDBC: [287]: cannot insert NULL or update to NULL: Not nullable "BPID" column; nested exception is com.sap.db.jdbc.exceptions.JDBCDriverException: SAP DBTech JDBC: [287]: cannot insert NULL or update to NULL: Not nullable "BPID" column

bpid 在 shema 中显然可以为空。这种消费领域的模糊性令人困惑。

如果 bpid 和 Identificationnumber 都设置了,那么数据库就不是问题。

我想存储一个对象,这两个 id 都可以为 null,但还想要一个唯一 id 作为 Identificationnumber。

我无法从客户那里调试 DEV 环境。知道这里可能会出现什么问题吗?

【问题讨论】:

【参考方案1】:

好的,所以你的IDENTIFICATIONNUMBER 永远不能为NULL。

基于提供的 DDL,它有一个 NOT NULL 约束,并且是单列主键,这隐含地使它成为 NOT NULL。

如果 H2 允许 NULL 插入,这是一个 H2 错误/不合规行为。

关于BPID 列,您似乎仍在尝试插入IDENTIFICATIONNUMBER 的值,即使该值被定义为IDENTITY 列。我假设,通过指定 NULL 作为它的值,你想让 HANA 使用 DEFAULT 值(序列)。

如果这是正确的,那么答案是:它不能这样工作。 另外:错误消息错误地将BPID 命名为有问题的字段。

在 HANA 的 INSERT 语句中使用 DEFAULT 值的正确方法是将应该使用 DEFAULT 值的列从列列表中删除。

SQL 标准还可以选择使用 DEFAULT 关键字,但不支持(目前是 HANA 2 SPS 04)。

【讨论】:

IDENTIFICATIONNUMBER 来自数据库本身。默认生成为 IDENTITY(START WITH 0) 基本上为每个新条目提供一个以 0、1、2 ... 等开头的新条目。H2 解决了这个问题。是不是走错路了? HAN​​A 对身份字段做同样的事情。这里的问题似乎是 - 正如我的回答中所解释的 - 您的 INSERT 命令将该列列为要插入的列之一。当您只是省略将实际值绑定到它时,这不起作用。您必须从插入命令中删除该列。 H2 historically 不仅允许DEFAULT,还允许将NULL 指定为identity 列的值;它们都被转换为生成的值;这就是为什么 H2 没有错误,但通常你应该使用DEFAULT。 (对于非身份列NULLDEFAULT 在H2 中是不同的东西。)通常不需要在INSERT 命令的列列表中列出身份列并指定其值。

以上是关于Hana DB 不允许在可空字段中使用空值的主要内容,如果未能解决你的问题,请参考以下文章

automapper如何全局配置map条件过滤null值空值对所有映射起效

C# 可空值类型

MS ACCESS 2016 - 使用 Null 进行查询的标准

强类型数据表/数据集中的可空类型 - 解决方法?

可空值和不可空值

如何使用带有可空值的吸气剂?