【问题标题】:SQL: Check Constraints to force a regex of arbitrary length?SQL:检查约束以强制使用任意长度的正则表达式?
【发布时间】:2019-12-12 15:18:15
【问题描述】:

我是正则表达式的新手,我正在使用 Postgres。我正在尝试在表中创建检查约束,以便某些列中的任何数据始终仅检查字母数字、数字、不带空格的字母数字等。

例如,给定一个像这样的表:

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_尼尔森

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+.+'
    );

谢谢!

【问题讨论】:

  • 你在使用 Postgresql 吗?`
  • 是的,我正在使用 Postgresql
  • 很高兴知道,不同的产品在正则表达式方面并不完全兼容。

标签: sql regex postgresql check-constraints


【解决方案1】:

类似于您的表达式的东西可以使用,但您的表达式包含 SQL 多字符通配符 ("%") 和正则表达式语法的混合。您应该消除“%”字符并根据需要修改正则表达式。例如,

'%\w%'

应该是

'.*\w*.*'

如果该列不可为空,则 \w* 应改为 \w+。其他表达方式也应类似修改。

【讨论】:

  • 是的,您的编辑看起来不错,因为它包含合法的正则表达式。 CHECK 语法使用逗号分隔不同列的表达式,但应改用AND。或者您可以使用三个不同的 CHECK 表达式。
  • 模式的开头和结尾不需要.*
  • @LaurenzAlba:啊,是的,你适合'\w' 模式。它应该包含在!~ '.*\s.*' 表达式中。
【解决方案2】:

有几点值得一提:

  • % 字符被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 检查将允许的不仅仅是“符号”; Unicode 包含许多不计为“空格”的控制代码和不可打印字符。您可能想改用显式白名单。

【讨论】:

    猜你喜欢
    • 2011-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-10
    • 1970-01-01
    相关资源
    最近更新 更多