我想在以下postgres表上设置检查约束:
CREATE TABLE foo
(
id int Primary Key,
names varchar(40)[]
);
由于names是一个数组,因此我无法定义对数组中每个元素的检查。 以下约束是我最好的猜测(不工作):
ALTER TABLE foo
ADD CONSTRAINT check_names
CHECK (ALL(names[]) ~* '^[A-Z]')
;
基本上,名称[]的每个元素都应该只用大写字母组成。
答案 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;