首页 > 解决方案 > 更改 Postgres 域的检查约束

问题描述

给定一个现有的DOMAIN带有CHECK约束的 Postgres:

CREATE DOMAIN code as CHAR(1) 
CHECK (value IN ('A', 'B', 'C'));

我需要更改CHECK约束以将D其作为成员添加到有效集合A中,B并且C.

由于新约束是第一个约束的超集,因此似乎可以接受先DROP存在现有约束,然后ADD再进行;IE:

ALTER DOMAIN code 
DROP CONSTRAINT code_check; -- constraint is implicitly named `code_check`

ALTER DOMAIN code 
ADD CONSTRAINT code_check 
CHECK (value IN ('A', 'B', 'C', 'D')); -- new constraint

这种方法可能存在问题,还是有更好的方法?

标签: postgresql

解决方案


理论上,并发会话可能会在域没有约束时插入违反约束的行。颠倒命令的顺序将防止这种可能性。由于新约束是旧约束的超集,您可以使用域禁止检查现有列中的值:

ALTER DOMAIN code 
ADD CONSTRAINT code_check_new 
CHECK (value IN ('A', 'B', 'C', 'D')) NOT VALID;

ALTER DOMAIN code 
DROP CONSTRAINT code_check;

-- if for some reason the constraint name is important:
ALTER DOMAIN code 
RENAME CONSTRAINT code_check_new TO code_check;

根据文档:

总是针对所有约束检查新插入或更新的行,即使是那些标记为 NOT VALID 的。


推荐阅读