将Oracle 11g模式转换为Postgresql 11时遇到了一个Oracle函数,如下所示:
ADD CONSTRAINT valid_session_time_zone CHECK (regexp_instr(trim(both session_time_zone),'(\+|\-|\s)?(0?[0-9]|1[01234])(:[0-5]\d)')=1);
所以我将其翻译为PostgreSQL 11域
CREATE DOMAIN chk_time_zone AS VARCHAR CHECK ( VALUE ~* '(\+|\-|\s)?(0?[0-9]|1[01234])(:[0-5]\d)');
但是如何在域表达式中预先修剪字符串的两侧?
答案 0 :(得分:1)
也许这只是我的视力不好,但在我看来原始代码有问题。原始的正则表达式要求匹配的字符串以+
,-
或空白之一开头,但是TRIM调用将删除所有前导空白。因此,如果要匹配的字符串以其后没有+
或-
的空格开头,则TRIM调用将删除该空格,因此该模式将不匹配。我的建议是仅忽略存在TRIM调用的事实,因为它似乎是潜在的错误,并以~* '(\+|\-|\s)?(0?[0-9]|1[01234])(:[0-5]\d)'
进行匹配。
答案 1 :(得分:0)
您的Oracle检查不会处理输入到表中的数据,它只是检查它的修剪版本是否与模式匹配,因此显然可以插入前导/尾随空格,或者其他地方也可以修剪它们...
因此,我认为您可以要求PGSQL通过在模式中允许它来忽略前导/尾随空格:
CREATE DOMAIN chk_time_zone AS VARCHAR CHECK
( VALUE ~* '\s*(\+|\-|\s)?(0?[0-9]|1[01234])(:[0-5]\d)\s*');
请注意,输入的正则表达式不包含开头或结尾的任何锚点,因此该模式可能出现在数据中的任何位置以进行匹配。如果输入必须完全匹配模式,则在正则表达式的开头添加^,在$的末尾添加$
例如:'abcdef'
匹配'[cd]+'
但不匹配'^[cd]+$'