简体   繁体   English

带有 ON CONFLICT 子句的 Postgres 条件插入

[英]Postgres conditional insert with an ON CONFLICT clause

I have the following table:我有下表:

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

In which I want to update the payment_status if it's changed:如果它发生变化,我想更新payment_status:

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

There's three possible payment statuses:有三种可能的付款状态:

  • Awaiting payment等待付款
  • Paid有薪酬的
  • Refunded已退款

The ON CONFLICT clause is there to update the order row when it changes from "Paid" to "Refunded". ON CONFLICT 子句用于在订单行从“已付款”更改为“已退款”时更新订单行。 However, the table should only contain rows for orders with status "Paid" or "Refunded", not "Awaiting Payment".但是,该表应该只包含状态为“已付款”或“已退款”的订单行,而不是“等待付款”的行。 If I specify a WHERE condition to the end of the statement as如果我在语句末尾指定 WHERE 条件为

WHERE EXCLUDED.payment_status != 'Awaiting payment'

This where-condition would only apply when there is a conflict on the primary key, not when a new order_id is inserted, thus letting orders with "Awaiting payment" status to pass on the first insert.此 where 条件仅适用于主键发生冲突时,而不适用于插入新的 order_id 时,从而让具有“等待付款”状态的订单在第一次插入时传递。

How can I do such an insert that allows only certain values of the payment_status to be inserted on the first insert?我怎样才能做这样一个插入,只允许在第一个插入时插入某些 pay_status 值?

The table should only contain rows for orders with status "Paid" or "Refunded", not "Awaiting Payment".该表应仅包含状态为“已付款”或“已退款”的订单行,而不是“等待付款”的行。

A CHECK constraint is the proper solution for that, and isn't limited to particular queries either. CHECK约束是正确的解决方案,也不限于特定查询。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM