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 个数字,可选地后跟一个大写字母(例如 1234
、1234A
):
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]?$
时,它可以同时匹配1234X
和1234
。 Here 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]?$'))
我正在使用 Oracle SQL,我想在创建 table 时添加一个检查正则表达式的 CHECK 约束。但是,REGEXP_LIKE 函数的行为与在线 RegEx 测试工具不同。
假设我想创建一个名为 Testing
的 table,只有一个名为 roomNo
的属性。我希望 roomNo
仅存储 4 个数字,可选地后跟一个大写字母(例如 1234
、1234A
):
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]?$
时,它可以同时匹配1234X
和1234
。 Here 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
.
因此,字符串 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]?$'))