允许空值时的最小长度约束
Minimum length constraint while allowing null values
假设我们有以下 table 结构
Name Null? Type
--------------------------- -------- -------------
ID NOT NULL NUMBER(15)
middle_name VARCHAR2(255)
如何在 middle_name
中插入的值必须具有最小长度的约束条件下强制执行,同时仍允许 null
值?
我尝试了以下约束
ALTER TABLE users
ADD CONSTRAINT check_middle_name CHECK (length(middle_name) > 1)
;
但它似乎有空值问题,因为我收到错误
SQL Error [2293] [23000]: ORA-02293: cannot validate (middle_name) - check constraint violated
您的代码运行良好。 Here 是一个 db<>fiddle,所以其他地方出了问题。
在where
和when
子句中,NULL
结果未通过比较并被视为“假”。 CHECK
约束的工作方式不同;只有明确的“假”值违反了约束。因此,NULL
值不会导致违规。
这是检查约束的 SQL 标准。这也是 Oracle 的工作方式。
除此之外,删除一个字符的中间名似乎不是个好主意。毕竟,Harry S Truman 的中间名只是“S”,举个例子。
问题不是由该列中的 null
引起的。相反,您的 table 中已经存在违反约束的数据,并且该数据是 middle_name
长度为 1 的行。例如,您可能 'F' 表示“John F Kennedy”已经在专栏中了。
您必须决定您需要如何处理那些违反所需约束的现有值。您可以修复它们(将它们更改为 null
或更长的字符串), 或 您可以保留它们并仅对未来的行强制执行约束。这很容易做到 - 在 alter table
中的 add constraint
子句末尾添加选项 novalidate
(就在分号之前)。
如果您使用 novalidate
选项添加约束,您仍然可以更新旧行,即使是那些中间名是单个字母的行 - 只要您只更新 other 列,不应用约束。即使在旧行中,您也无法将中间名更新为单个字母;该列中的任何新值都必须遵守约束,即使“新值”适用于“旧行”。
假设我们有以下 table 结构
Name Null? Type
--------------------------- -------- -------------
ID NOT NULL NUMBER(15)
middle_name VARCHAR2(255)
如何在 middle_name
中插入的值必须具有最小长度的约束条件下强制执行,同时仍允许 null
值?
我尝试了以下约束
ALTER TABLE users
ADD CONSTRAINT check_middle_name CHECK (length(middle_name) > 1)
;
但它似乎有空值问题,因为我收到错误
SQL Error [2293] [23000]: ORA-02293: cannot validate (middle_name) - check constraint violated
您的代码运行良好。 Here 是一个 db<>fiddle,所以其他地方出了问题。
在where
和when
子句中,NULL
结果未通过比较并被视为“假”。 CHECK
约束的工作方式不同;只有明确的“假”值违反了约束。因此,NULL
值不会导致违规。
这是检查约束的 SQL 标准。这也是 Oracle 的工作方式。
除此之外,删除一个字符的中间名似乎不是个好主意。毕竟,Harry S Truman 的中间名只是“S”,举个例子。
问题不是由该列中的 null
引起的。相反,您的 table 中已经存在违反约束的数据,并且该数据是 middle_name
长度为 1 的行。例如,您可能 'F' 表示“John F Kennedy”已经在专栏中了。
您必须决定您需要如何处理那些违反所需约束的现有值。您可以修复它们(将它们更改为 null
或更长的字符串), 或 您可以保留它们并仅对未来的行强制执行约束。这很容易做到 - 在 alter table
中的 add constraint
子句末尾添加选项 novalidate
(就在分号之前)。
如果您使用 novalidate
选项添加约束,您仍然可以更新旧行,即使是那些中间名是单个字母的行 - 只要您只更新 other 列,不应用约束。即使在旧行中,您也无法将中间名更新为单个字母;该列中的任何新值都必须遵守约束,即使“新值”适用于“旧行”。