Postrgesql - 检查定义为数组的表列的约束

时间:2016-01-19 10:54:35

标签: postgresql

我想在以下postgres表上设置检查约束:

 CREATE TABLE foo
(
     id int Primary Key,
     names           varchar(40)[]  
);

由于names是一个数组,因此我无法定义对数组中每个元素的检查。 以下约束是我最好的猜测(不工作):

ALTER TABLE foo
    ADD CONSTRAINT check_names
        CHECK (ALL(names[]) ~* '^[A-Z]')
;

基本上,名称[]的每个元素都应该只用大写字母组成。

2 个答案:

答案 0 :(得分:5)

即使没有单独的触发功能,它仍然可行:

CREATE TABLE foo(
     id int Primary Key,
     names           varchar(40)[]
);

ALTER TABLE foo
  ADD CONSTRAINT check_names
    CHECK (length(regexp_replace(array_to_string(names, ''),'[A-Z]*',''))=0);

INSERT INTO foo (id, names) VALUES (4, array ['','3']);
ERROR:  new row for relation "foo" violates check constraint "check_names"
DETAIL:  Failing row contains (4, {"",3}).

答案 1 :(得分:2)

就像pozs对你的帖子发表评论一样,据我所知,你不能在这个阵列上设置这样的CHECK约束(真正的专业人士可以在这里纠正我)。

你可以做的是写一个BEFORE INSERT触发器,在names字段插入表之前检查它的值。实际上就像CONSTRAINT一样。显然,这不适用于表中已有的行。

CREATE FUNCTION all_caps_array_only() RETURNS trigger AS $$
DECLARE
  name varchar(40);
BEGIN
  FOREACH name IN ARRAY NEW.names LOOP
    IF name !~ '[A-Z]+' THEN
      RETURN NULL; -- Fail the INSERT
    END IF;
  END LOOP;
  RETURN NEW; -- Make the INSERT happen
END;
$$ LANGUAGE plpgsql;