检查数据是否具有默认长度,并且它是sql中的数字

时间:2017-08-30 14:09:29

标签: sql postgresql postgresql-9.4

在我的表中,我有一个6位代码的列。

myCode CHAR(6) PRIMARY KEY CHECK ( SUBSTRING ( myCode ,1 ,1) >='0' AND
SUBSTRING ( myCode ,1 ,1) <= '9' AND ...#for all positions

还有另一种比这更快的方法吗?

2 个答案:

答案 0 :(得分:4)

使用正则表达式:

CREATE TABLE tabq(myCode CHAR(6) PRIMARY KEY CHECK (myCode ~'^([0-9]{6})$') );

如果您只想识别匹配此模式的记录,您可以尝试:

SELECT *
FROM tabq
WHERE myCode !~ '^\\d{6}$';

<强> Rextester Demo

答案 1 :(得分:2)

简单:

mycode ~ '\d{6}'

\d is the class shorthand for digits
使用其他\转义\,除非您使用已过时的standard_conforming_strings = off。见:

不需要括号。
在使用^时,您甚至不需要$char(6)来锚定表达式的开始和结束(即使这不会造成伤害)。一种罕见的用例,其中数据类型并非完全无意义。参见:

较短的字符串是空白填充的,不会传递CHECK约束 较长的字符串不会传递char(6)类型的长度规范 (但要小心!像'1234567'::char(6)这样的显式强制转换会默默地截断。)

CREATE TABLE tbl (mycode char(6) PRIMARY KEY CHECK (mycode ~ '\d{6}'));

我仍然建议不要使用过时的char(6)类型。角落情况下的奇怪行为。请改用text。然后你在regexp表达式中实际需要^$

CREATE TABLE tbl (mycode text PRIMARY KEY CHECK (mycode ~ '^\d{6}$'));

dbfiddle here

你评论过(真的是一个新问题):

  

那里面的数字必须与众不同?

在字符串中强制使用唯一数字并不简单。如果您安装了additional module intarray,则会有sort()uniq()的优雅解决方案:

CREATE TEMP TABLE tbl3 (
   mycode varchar(6) PRIMARY KEY
 , CONSTRAINT chk_6_distinct_digits
      CHECK (cardinality(uniq(sort(string_to_array(mycode, NULL)::int[]))) = 6)
);