Oracle SQL - REGEXP_LIKE 在 CHECK 约束中未按预期工作

Oracle SQL - REGEXP_LIKE not working as expected in CHECK constraint

我正在使用 Oracle SQL,我想在创建 table 时添加一个检查正则表达式的 CHECK 约束。但是,REGEXP_LIKE 函数的行为与在线 RegEx 测试工具不同。

假设我想创建一个名为 Testing 的 table,只有一个名为 roomNo 的属性。我希望 roomNo 仅存储 4 个数字,可选地后跟一个大写字母(例如 12341234A):

CREATE TABLE Testing (
    roomNo      char(5),
    CONSTRAINT check_roomNo CHECK (REGEXP_LIKE(roomNo, '^\d{4}[A-Z]?$'))
);
insert into Testing values ('1234X');
insert into Testing values ('1234');  -- Unexpected error here

当我 运行 这个脚本时,我可以成功地将 1234X 插入 table 但是 Oracle SQL 在插入 1234 时抛出一个错误:

Error starting at line : 5 in command -
insert into Testing values ('1234')
Error report -
ORA-02290: check constraint (USER.CHECK_ROOMNO) violated

我不太明白为什么会出现这个错误,因为当我在在线正则表达式测试工具中测试正则表达式^\d{4}[A-Z]?$时,它可以同时匹配1234X1234Here is a link 到使用我在 REGEXP_LIKE 函数中使用的 RegEx 的 RegEx 测试工具。非常感谢!

经过一些挖掘,我发现数据类型为 char(5)roomNo 是这个问题的罪魁祸首。

根据关于 char in here 的 Oracle 文档:

When you insert a character value into a CHAR database column, Oracle does not strip trailing blanks. If the value is shorter than the defined width of the column, Oracle blank-pads the value to the defined width

当我将 1234 插入 table 时,由于 1234 的长度比列的定义宽度(即宽度 5)短,Oracle 添加了空白垫在字符串的右侧,以便字符串存储为 1234 ,在 1234.

之后有一个空格 space

因此,字符串 1234 无法匹配正则表达式 ^\d{4}[A-Z]?$,因为字符串的最后一个字符(即空白 space)与 [A-Z] 不匹配.

我能想到的一个解决方案是使用 ^\d{4}[A-Z ]?$ 的正则表达式,这样它就可以匹配位于第 5 个字符的单个空白 space。

编辑:

另一种解决方法是使用RTRIM()函数去除右边的拖尾白spaces:

CONSTRAINT check_roomNo CHECK (REGEXP_LIKE(RTRIM(roomNo), '^\d{4}[A-Z]?$'))