PostgreSQL检查约束不起作用

时间:2014-04-24 06:44:27

标签: regex postgresql

我试图在postgresql中获得低于约束的工作,它检查模式的列wcode。如果模式不匹配则应抛出错误。

CONSTRAINT wcoding CHECK (wcode::text ~ '[\w]{4,4}-[\w]{2,2}-[\w]{1,1}'::text);

Geniun输入字符串是“AA14-AM-1”。这实际上有效。但问题是如果我输入“AA14-AM-14”或“AA14-AM-1444”,它不会通过错误。我想限制输入使用这个(“AA14-AM-1”)模式。

3 个答案:

答案 0 :(得分:2)

你有一个“无限制”的正则表达式(不确定这是否是正确的技术术语)。这实际上意味着模式必须出现在输入字符串内的任何位置。要将输入字符串与完全模式匹配,您需要一个“锚定”的正则表达式:

CONSTRAINT wcoding CHECK (wcode::text ~ '^[\w]{4,4}-[\w]{2,2}-[\w]{1,1}$');

^$“锚定”开始和结束时的模式,这导致输入字符串必须与模式完全匹配(不允许模式作为a的子字符串)更长的投入价值)。​​

答案 1 :(得分:2)

@a_horse阐明了^$的作用。但整体简化:

ALTER TABLE ADD CONSTRAINT wcoding
CHECK (wcode::text ~ '^\w{4}-\w\w-\w$');

您不需要class shorthands like \w的字符类 为什么有text演员?可能是多余的。

SQL Fiddle.

答案 2 :(得分:1)

Malav,在PostgreSQL中,这个紧凑的正则表达式可以满足您的需求:

第一种方法

[\w]{4}-[\w]{2}-\w(?!=\w)

第二种方法

[\w]{4}-[\w]{2}-\w\y

请注意,您可以将{4,4}写为“恰好四次”,而不是{4}

这是如何运作的?

在最后一个单词后,我们检查没有其他单词字符。为此,在第一种方法中,我们使用否定前瞻(?=\w)

在第二种方法中,我们使用单词边界\y(在大多数正则表达式中我会在末尾添加单词边界\b,但在PostgreSQL中它是\y)< / p>

这就是为什么在第一个版本中我使用了负面的前瞻(更便携)。使用您喜欢的任何版本。