首页 > 解决方案 > 带有 ON CONFLICT 子句的 Postgres 条件插入

问题描述

我有下表:

CREATE TABLE orders(
     order_id text primary key,
     payment_status text not null
)

如果更改,我想在其中更新 payment_status :

INSERT INTO orders(
        order_id, 
        payment_status
)
VALUES(
        '101',
        'Paid'
)
ON CONFLICT (order_id) DO UPDATE SET
        payment_status = EXCLUDED.payment_status

有三种可能的付款状态:

ON CONFLICT 子句用于在订单行从“已付款”更改为“已退款”时更新订单行。但是,该表应该只包含状态为“已付款”或“已退款”的订单行,而不是“等待付款”的订单行。如果我在语句末尾指定 WHERE 条件为

WHERE EXCLUDED.payment_status != 'Awaiting payment'

此 where 条件仅在主键发生冲突时适用,而不是在插入新的 order_id 时适用,从而让具有“等待付款”状态的订单在第一次插入时传递。

如何进行这样的插入,只允许在第一次插入时插入 payment_status 的某些值?

标签: postgresql

解决方案


该表应仅包含状态为“已付款”或“已退款”的订单行,而不是“等待付款”的订单行。

CHECK约束是适当的解决方案,并且也不限于特定查询。

CREATE TABLE orders(
     order_id text primary key,
     payment_status text not null CHECK (payment_status IN ('Paid', 'Refunded'))
)

推荐阅读