微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

create table test
(

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

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

我希望此检查约束停止此插入。但是,它仍然被插入。为什么?

解决方法

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

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

试试TRIM(ID) IS NOT NULL

声明约束可以返回 null aka 'unknown' 并被认为不违反约束的代码段。只有返回 false 才违反约束。至少按照 Oracle 12c

See Oracle Concept page about constraints

Snippet stating that constraints can return null aka 'unknown'

,

对所见所闻的解释:

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

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

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

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

  5. 检查约束中,unknown 被视为与 true 相同。这与其他条件(在 SQL 语句中 - 在 where 子句、连接条件等中)中的处理不同,其中 unknown 被视为与 false 相同。例如,这里记录了这一点:https://docs.oracle.com/cd/B19306_01/server.102/b14200/clauses002.htm - 请参阅检查约束部分的第一段。

问题的正确解决方案:

直接检查某些内容是否为空,使用 is nullis not null 条件。不要为此使用 length

像这样:

check( trim(id) is not null )

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。