PostgreSQL - 多重约束
PostgreSQL - Multiple constraints
我想添加几个 CHECK CONSTRAINTS
到 PostgreSQL 13 table。在自然语言逻辑中是:如果一个字段包含定义的值,则必须填充另一个字段。我有几个场景可以结合起来。当我只添加一个约束时没问题,但是当我想累积它们时,CONSTRAINTS
不受尊重并且无法插入行。
这是我的 table:
CREATE TABLE IF NOT EXISTS demo_table
(
uuid uuid NOT NULL DEFAULT uuid_generate_v4(),
id integer NOT NULL DEFAULT nextval('demo_table_id_seq'::regclass),
thematic character varying COLLATE pg_catalog."default",
field_a character varying COLLATE pg_catalog."default",
field_b character varying COLLATE pg_catalog."default",
CONSTRAINT demo_table_pkey PRIMARY KEY (uuid),
CONSTRAINT field_a_check CHECK (thematic::text ~~ 'A'::text AND field_a IS NOT NULL),
CONSTRAINT field_b_check CHECK (thematic::text ~~ 'B'::text AND field_b IS NOT NULL)
)
我预期的逻辑是:当 thematic
像 'A
' 时,field_a
不能是 NULL
或者当 thematic
像 'B
' field_b
不能是 NULL
。使用此设置我无法添加行,因为我的 CONSTRAINTS
定义从不检查这两个条件 (field_a IS NOT NULL and field_b IS NOT NULL
).
我试图按照此 中的建议定义一个唯一的 CONSTRAINT
,但 CHECK CONSTRAINT
也不受尊重,因为隔离条件的括号未保存在定义中。
CREATE TABLE IF NOT EXISTS demo_table
(
uuid uuid NOT NULL DEFAULT uuid_generate_v4(),
id integer NOT NULL DEFAULT nextval('demo_table_id_seq'::regclass),
thematic character varying COLLATE pg_catalog."default",
field_a character varying COLLATE pg_catalog."default",
field_b character varying COLLATE pg_catalog."default",
CONSTRAINT demo_table_pkey PRIMARY KEY (uuid),
CONSTRAINT field_a_b_check CHECK (thematic::text ~~ 'A'::text AND field_a IS NOT NULL OR thematic::text ~~ 'B'::text AND field_b IS NOT NULL)
)
如何组合多个 CONSTRAINTS
比如 (IF ... ) OR (IF ... ) OR (IF ...)
?
你的方法的问题是你的约束不完整。
例如:
CONSTRAINT field_a_check CHECK (thematic::text ~~ 'A'::text AND field_a IS NOT NULL),
约束表示“如果 thematic
包含 'A' 且 field_a
不为空,则记录正常”。这意味着记录不正确(如果它不包含 'A')。如果您在支票上附加了“否则还可以”,那么您可能会有几个 - 没问题:
CONSTRAINT field_a_check CHECK (thematic::text ~~ 'A'::text AND field_a IS NOT NULL OR NOT thematic::text ~~ 'A'::text)
至于为什么删除括号 - 这是因为不需要它们。 AND 运算符优先于 OR,所以表达式有无括号都是一样的。
欢迎您在db<>fiddle
查看解决方案
你可以这样做。
alter table table_1
add constraint ck_only_one check ((col1 is null and col2 is not null) or (col2 is null and col1 is not null));
为了更好地隔离,要用括号分隔。
我想添加几个 CHECK CONSTRAINTS
到 PostgreSQL 13 table。在自然语言逻辑中是:如果一个字段包含定义的值,则必须填充另一个字段。我有几个场景可以结合起来。当我只添加一个约束时没问题,但是当我想累积它们时,CONSTRAINTS
不受尊重并且无法插入行。
这是我的 table:
CREATE TABLE IF NOT EXISTS demo_table
(
uuid uuid NOT NULL DEFAULT uuid_generate_v4(),
id integer NOT NULL DEFAULT nextval('demo_table_id_seq'::regclass),
thematic character varying COLLATE pg_catalog."default",
field_a character varying COLLATE pg_catalog."default",
field_b character varying COLLATE pg_catalog."default",
CONSTRAINT demo_table_pkey PRIMARY KEY (uuid),
CONSTRAINT field_a_check CHECK (thematic::text ~~ 'A'::text AND field_a IS NOT NULL),
CONSTRAINT field_b_check CHECK (thematic::text ~~ 'B'::text AND field_b IS NOT NULL)
)
我预期的逻辑是:当 thematic
像 'A
' 时,field_a
不能是 NULL
或者当 thematic
像 'B
' field_b
不能是 NULL
。使用此设置我无法添加行,因为我的 CONSTRAINTS
定义从不检查这两个条件 (field_a IS NOT NULL and field_b IS NOT NULL
).
我试图按照此 CONSTRAINT
,但 CHECK CONSTRAINT
也不受尊重,因为隔离条件的括号未保存在定义中。
CREATE TABLE IF NOT EXISTS demo_table
(
uuid uuid NOT NULL DEFAULT uuid_generate_v4(),
id integer NOT NULL DEFAULT nextval('demo_table_id_seq'::regclass),
thematic character varying COLLATE pg_catalog."default",
field_a character varying COLLATE pg_catalog."default",
field_b character varying COLLATE pg_catalog."default",
CONSTRAINT demo_table_pkey PRIMARY KEY (uuid),
CONSTRAINT field_a_b_check CHECK (thematic::text ~~ 'A'::text AND field_a IS NOT NULL OR thematic::text ~~ 'B'::text AND field_b IS NOT NULL)
)
如何组合多个 CONSTRAINTS
比如 (IF ... ) OR (IF ... ) OR (IF ...)
?
你的方法的问题是你的约束不完整。 例如:
CONSTRAINT field_a_check CHECK (thematic::text ~~ 'A'::text AND field_a IS NOT NULL),
约束表示“如果 thematic
包含 'A' 且 field_a
不为空,则记录正常”。这意味着记录不正确(如果它不包含 'A')。如果您在支票上附加了“否则还可以”,那么您可能会有几个 - 没问题:
CONSTRAINT field_a_check CHECK (thematic::text ~~ 'A'::text AND field_a IS NOT NULL OR NOT thematic::text ~~ 'A'::text)
至于为什么删除括号 - 这是因为不需要它们。 AND 运算符优先于 OR,所以表达式有无括号都是一样的。
欢迎您在db<>fiddle
查看解决方案你可以这样做。
alter table table_1
add constraint ck_only_one check ((col1 is null and col2 is not null) or (col2 is null and col1 is not null));
为了更好地隔离,要用括号分隔。