为什么这个检查约束在检查长度时不起作用?

Why is this check constraint not working when it checks length?

create table test
(

   id varchar2(10) check( length(trim(id)) > 0),
   primary key(id)
)

insert into test values (' '); -- this works

我预计此检查约束会停止此插入。但是,它被插入的次数越少none。为什么?

问题是 TRIM(' ') returns NULLLENGTH(NULL) 也给出 NULL(不是 0)

尝试NVL(LENGTH(TRIM(' ')), 0) > 0

尝试TRIM(ID) IS NOT NULL

声明约束可以 return null 又名 'unknown' 并且被认为不违反约束的片段。只有 return 的 false 违反约束。至少按照 Oracle 12c

See Oracle Concept page about constraints

对所见内容的解释:

  1. 如果str完全由空格组成,那么trim(str)就是空字符串。

  2. Oracle 将“空字符串”视为与 nullvarchar2 数据类型,当重要时)相同,公然违反了 SQL标准。 Oracle 在这方面甚至不一致 - 有(极少数)例外情况,空字符串实际上被视为“空字符串”(例如,在连接中)。

  3. 根据定义,null的长度是null(特别是,不是零)。

  4. 在SQL中,像null > 0这样的条件的计算结果为unknown(在这种条件下需要容纳null的三值逻辑).

  5. 中检查约束 unknowntrue 的处理方式相同。这不同于其他条件的处理(在 SQL 语句中 - 在 where 子句中,连接条件等),其中 unknownfalse 相同。例如,此处记录了这一点:https://docs.oracle.com/cd/B19306_01/server.102/b14200/clauses002.htm - 请参阅 检查约束 部分的第一段。

您问题的正确解法:

检查是否为 null 应该 DIRECTLY,使用 is nullis not null 条件。不要为此使用 length

像这样:

check( trim(id) is not null )