为什么这个检查约束在检查长度时不起作用?
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 NULL
和 LENGTH(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
对所见内容的解释:
如果str
完全由空格组成,那么trim(str)
就是空字符串。
Oracle 将“空字符串”视为与 null
(varchar2
数据类型,当重要时)相同,公然违反了 SQL标准。 Oracle 在这方面甚至不一致 - 有(极少数)例外情况,空字符串实际上被视为“空字符串”(例如,在连接中)。
根据定义,null
的长度是null
(特别是,不是零)。
在SQL中,像null > 0
这样的条件的计算结果为unknown
(在这种条件下需要容纳null
的三值逻辑).
在中检查约束 unknown
与true
的处理方式相同。这不同于其他条件的处理(在 SQL 语句中 - 在 where
子句中,连接条件等),其中 unknown
与 false
相同。例如,此处记录了这一点:https://docs.oracle.com/cd/B19306_01/server.102/b14200/clauses002.htm - 请参阅 检查约束 部分的第一段。
您问题的正确解法:
检查是否为 null 应该 DIRECTLY,使用 is null
或 is not null
条件。不要为此使用 length
。
像这样:
check( trim(id) is not null )
create table test
(
id varchar2(10) check( length(trim(id)) > 0),
primary key(id)
)
insert into test values (' '); -- this works
我预计此检查约束会停止此插入。但是,它被插入的次数越少none。为什么?
问题是 TRIM(' ')
returns NULL
和 LENGTH(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
对所见内容的解释:
如果
str
完全由空格组成,那么trim(str)
就是空字符串。Oracle 将“空字符串”视为与
null
(varchar2
数据类型,当重要时)相同,公然违反了 SQL标准。 Oracle 在这方面甚至不一致 - 有(极少数)例外情况,空字符串实际上被视为“空字符串”(例如,在连接中)。根据定义,
null
的长度是null
(特别是,不是零)。在SQL中,像
null > 0
这样的条件的计算结果为unknown
(在这种条件下需要容纳null
的三值逻辑).在中检查约束
unknown
与true
的处理方式相同。这不同于其他条件的处理(在 SQL 语句中 - 在where
子句中,连接条件等),其中unknown
与false
相同。例如,此处记录了这一点:https://docs.oracle.com/cd/B19306_01/server.102/b14200/clauses002.htm - 请参阅 检查约束 部分的第一段。
您问题的正确解法:
检查是否为 null 应该 DIRECTLY,使用 is null
或 is not null
条件。不要为此使用 length
。
像这样:
check( trim(id) is not null )