PostgreSQL:为personnes表添加多列CHECK约束的问题
为personnes表添加符合要求的CHECK约束
现有表信息
建表语句:
jouer=# create table personnes ( g_name VARCHAR ( 50 ), f_name VARCHAR ( 50 ) UNIQUE, company BOOLEAN NOT NULL DEFAULT false) ;
建表后的表结构:
Colonne | Type | Collationnement | NULL-able | Par défaut ---------+-----------------------+-----------------+-----------+------------ g_name | character varying(50) | | | f_name | character varying(50) | | | company | boolean | | not null | false
约束需求
- 当
company为true时,g_name和f_name必须为null; - 当
company为false时,g_name和f_name必须均不为null。
尝试过的错误语句
第一种:
jouer=# ALTER TABLE personnes ADD CONSTRAINT personnes_company_check CHECK ( company is false and g_name is not null and f_name is not null) ; ALTER TABLE
该约束仅限制了company=false的场景,完全未覆盖company=true时的要求,导致company=true时即使g_name或f_name不为空也能插入数据,不符合需求。
第二种:
jouer=# ALTER TABLE personnes ADD CONSTRAINT personnes_company_check CHECK ( company is true and g_name is null and f_name is null) ;
该约束仅限制了company=true的场景,company=false时无论g_name和f_name是否为空都能插入,同样不满足要求。
正确的CHECK约束语句
需要将两种场景用逻辑或(OR)组合,完整覆盖所有情况:
jouer=# ALTER TABLE personnes ADD CONSTRAINT personnes_company_check CHECK ( (company = true AND g_name IS NULL AND f_name IS NULL) OR (company = false AND g_name IS NOT NULL AND f_name IS NOT NULL) );
另外,由于company字段是NOT NULL的,还可以用更简洁的等价写法:
jouer=# ALTER TABLE personnes ADD CONSTRAINT personnes_company_check CHECK ( (company = (g_name IS NULL)) AND (company = (f_name IS NULL)) );
这个写法的逻辑是:company的值必须和g_name IS NULL、f_name IS NULL的结果完全一致——当company=true时,g_name和f_name都得是null;当company=false时,g_name和f_name都不能是null,完美匹配需求。
内容的提问来源于stack exchange,提问作者thiebo
相关产品推荐
相关产品推荐

