SQL:检查约束以强制使用任意长度的正则表达式?
SQL: Check Constraints to force a regex of arbitrary length?
我是正则表达式的新手,我正在使用 Postgres。我正在尝试在 table 中进行检查约束,以便某些列中的任何数据始终只检查字母数字、数字、不带空格的字母数字等
例如,给定一个 table 像:
CREATE TABLE client (
PRIMARY KEY (id),
id CHAR(18) NOT NULL,
name TEXT NOT NULL,
promo_code TEXT NOT NULL
);
我想用 CHECK 做一个约束,只允许 id 中没有空格的字母数字内容,名称中有空格的字母数字,promo_code 中有符号的没有空格内容的字母数字。
id 的长度严格为 18,但 name 和 promo_code 的长度可变。
像下面这样的东西行得通吗?
ALTER TABLE client
ADD CONSTRAINT ck_client_one
CHECK (
id ~ '%\w%' AND id !~ '%\s%',
name ~ '%\w%' AND name !~ '%\d%',
promo_code ~ '%\w%' OR promo_code ~ '%\W%' AND promo_code !~ '%\s%'
);
ALTER TABLE client
ADD CONSTRAINT ck_client_two
CHECK (
id ~ '%^[a-zA-Z0-9]*%' AND id !~ '%\s%',
name ~ '%^[a-zA-Z]*%',
promo_code ~ '%^[a-zA-Z0-9]*%' OR promo_code !~ '%^[a-zA-Z0-9]*%'
AND promo_code !~ '%\s%'
);
rd_nielsen
ALTER TABLE client
ADD CONSTRAINT ck_client_one
CHECK (
id ~ '.+\w+.+' AND id !~ '.+\s+.+',
name ~ '.+\w+.+' AND name !~ '.+\d+.+',
promo_code ~ '.+\w+.+' OR promo_code ~ '.+\W+.+'
AND promo_code !~ '.+\s+.+'
);
谢谢!
类似于您的表达式的东西可以工作,但您的表达式包含 SQL 多字符通配符 ("%") 和正则表达式语法的混合。您应该删除“%”字符并根据需要修改正则表达式。例如,
'%\w%'
应该是
'.*\w*.*'
如果该列不可为空,则 \w*
应该改为 \w+
。其他表达式类似修改。
有几点值得一提:
-
%
字符被 LIKE
表达式用作零个或多个通配符。等价的正则表达式是 .*
.
- 如果你想匹配整个字符串,那么你需要用
^
和$
来锚定开始和结束。
- 相反,未锚定的模式表现得好像两端都有通配符;例如,
\s
与 ^.*\s.*$
相同。
\w
匹配下划线,\s
匹配制表符和换行符,您可能不想允许这些。
~*
运算符执行不区分大小写的匹配,让您将 [A-Za-z]
简化为 [a-z]
。
考虑到所有这些:
id ~* '^[a-z0-9]{18}$'
name ~* '^[a-z ]*$'
promo_code !~ '\s'
如果您想确保 name
不完全为空,请改用 ^[a-z ]+$
。
promo_code
检查将允许的不仅仅是 "symbols"; Unicode 包含许多控制代码和不可打印的字符,这些字符不算作 "space"。您可能想改用显式白名单。
我是正则表达式的新手,我正在使用 Postgres。我正在尝试在 table 中进行检查约束,以便某些列中的任何数据始终只检查字母数字、数字、不带空格的字母数字等
例如,给定一个 table 像:
CREATE TABLE client (
PRIMARY KEY (id),
id CHAR(18) NOT NULL,
name TEXT NOT NULL,
promo_code TEXT NOT NULL
);
我想用 CHECK 做一个约束,只允许 id 中没有空格的字母数字内容,名称中有空格的字母数字,promo_code 中有符号的没有空格内容的字母数字。 id 的长度严格为 18,但 name 和 promo_code 的长度可变。
像下面这样的东西行得通吗?
ALTER TABLE client
ADD CONSTRAINT ck_client_one
CHECK (
id ~ '%\w%' AND id !~ '%\s%',
name ~ '%\w%' AND name !~ '%\d%',
promo_code ~ '%\w%' OR promo_code ~ '%\W%' AND promo_code !~ '%\s%'
);
ALTER TABLE client
ADD CONSTRAINT ck_client_two
CHECK (
id ~ '%^[a-zA-Z0-9]*%' AND id !~ '%\s%',
name ~ '%^[a-zA-Z]*%',
promo_code ~ '%^[a-zA-Z0-9]*%' OR promo_code !~ '%^[a-zA-Z0-9]*%'
AND promo_code !~ '%\s%'
);
rd_nielsen
ALTER TABLE client
ADD CONSTRAINT ck_client_one
CHECK (
id ~ '.+\w+.+' AND id !~ '.+\s+.+',
name ~ '.+\w+.+' AND name !~ '.+\d+.+',
promo_code ~ '.+\w+.+' OR promo_code ~ '.+\W+.+'
AND promo_code !~ '.+\s+.+'
);
谢谢!
类似于您的表达式的东西可以工作,但您的表达式包含 SQL 多字符通配符 ("%") 和正则表达式语法的混合。您应该删除“%”字符并根据需要修改正则表达式。例如,
'%\w%'
应该是
'.*\w*.*'
如果该列不可为空,则 \w*
应该改为 \w+
。其他表达式类似修改。
有几点值得一提:
-
%
字符被LIKE
表达式用作零个或多个通配符。等价的正则表达式是.*
. - 如果你想匹配整个字符串,那么你需要用
^
和$
来锚定开始和结束。- 相反,未锚定的模式表现得好像两端都有通配符;例如,
\s
与^.*\s.*$
相同。
- 相反,未锚定的模式表现得好像两端都有通配符;例如,
\w
匹配下划线,\s
匹配制表符和换行符,您可能不想允许这些。~*
运算符执行不区分大小写的匹配,让您将[A-Za-z]
简化为[a-z]
。
考虑到所有这些:
id ~* '^[a-z0-9]{18}$'
name ~* '^[a-z ]*$'
promo_code !~ '\s'
如果您想确保 name
不完全为空,请改用 ^[a-z ]+$
。
promo_code
检查将允许的不仅仅是 "symbols"; Unicode 包含许多控制代码和不可打印的字符,这些字符不算作 "space"。您可能想改用显式白名单。