You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 04:50:25