根据另一个值更改列的约束

Kin*_*ull 6 postgresql constraint condition check-constraints

是否可以根据另一列的值更改 postgres 中列的约束?例如(伪代码):

CREATE TABLE transactions(
    id SERIAL PRIMARY KEY,
    type TXN_TYPE NOT NULL,
    amount BIGINT,
    . . . .,
    refunded boolean DEFAULT FALSE,
    refund_id DEFAULT NULL if (CONSTRAINT link_refund CHECK (refunded=TRUE))=TRUE REFERENCES transactions(id)
);
Run Code Online (Sandbox Code Playgroud)

a_h*_*ame 7

外键不能是“有条件的”。该规则唯一的“例外”是null不能根据定义引用另一个表的值。

如果我正确理解您的问题,您正在尝试实施一个约束,即“如果退款,truerefund_id必须参考现有交易”。

我认为您根本不需要refunded专栏。因为标志refunded可以从refund_id 使用表达式的值派生:refund_id is not null

如果您确实想要这样的列,只需使用该表达式创建一个视图。

如果您确实坚持使用冗余refunded标志,则可以设置如下检查约束:

CREATE TABLE transactions(
    id SERIAL PRIMARY KEY,
    type TXN_TYPE NOT NULL,
    amount BIGINT,
    . . . .,
    refunded boolean DEFAULT FALSE,
    refund_id integer null REFERENCES transactions,
    constraint check_refund 
       check ( (refunded and refund_id is not null or
               (not refunded and refund_id is null) ) 
);
Run Code Online (Sandbox Code Playgroud)