我需要一个查询来更新表中的一行,但如果 id 不存在,它会插入默认值。它还必须避免线程竞争条件。
我在这里找到了一个应该没问题的答案 https://stackoverflow.com/a/7927957/8372336
使用此查询:
UPDATE tbl x
SET tbl_id = 24
, name = 'New Gal'
FROM (SELECT tbl_id, name FROM tbl WHERE tbl_id = 4 FOR UPDATE) y
WHERE x.tbl_id = y.tbl_id
RETURNING y.tbl_id AS old_id, y.name AS old_name, x.tbl_id, x.name;
所以我认为它应该在更新后返回旧值,并且应该防止线程竞争条件。
但是如果该行不存在,我需要添加一个插入,并且这次还返回插入的值(旧值没有意义,因为它们不存在)。
所以基本上我需要做类似的事情
INSERT INTO tbl
(...) VALUES (...)
RETURNING ..., ...
ON CONFLICT DO
UPDATE tbl x
SET tbl_id = 24
, name = 'New Gal'
FROM (SELECT tbl_id, name FROM tbl WHERE tbl_id = 4 FOR UPDATE) y
WHERE x.tbl_id = y.tbl_id
RETURNING y.tbl_id AS old_id, y.name AS old_name, x.tbl_id, x.name;
但我不确定这样的事情是否可行。我怎样才能让它工作并确保比赛条件?