允许空值时的最小长度约束

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,所以其他地方出了问题。

wherewhen子句中,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 列,不应用约束。即使在旧行中,您也无法将中间名更新为单个字母;该列中的任何新值都必须遵守约束,即使“新值”适用于“旧行”。