vol*_*ron 5 sql postgresql common-table-expression postgresql-9.2
从表中删除,然后插入到同一个表并返回插入值的 CTE 语法是什么?
运行 2 小时的睡眠,有些事情看起来不对劲(除了这不会执行的事实):
WITH delete_rows AS (
DELETE FROM <some_table> WHERE id = <id_value>
RETURNING *
)
SELECT * FROM delete_rows
UNION
(
INSERT INTO <some_table> ( id, text_field )
VALUES ( <id_value>, '<text_field_value>' )
RETURNING *
)
Run Code Online (Sandbox Code Playgroud)
预期的行为是首先清除一个 ID 的所有记录,然后插入相同 ID 的记录(故意不是 upsert)并返回那些插入的记录(不是删除)。
您的问题更新明确表明您不能在一个声明中做到这一点。
打包到同一语句的 CTE 中,两个操作(INSERT和DELETE)将看到表的相同快照并几乎同时执行。即,INSERT仍然会看到您认为已经删除的所有行。根据文档:
所有语句都使用相同的快照执行(参见第 13 章),因此它们无法“看到”彼此对目标表的影响。
您可以将它们作为两个独立的语句包装到同一个事务中——这似乎也不是绝对必要的,但它会允许整个操作以原子方式成功/失败:
BEGIN;
DELETE FROM <some_table> WHERE id = <id_value>;
INSERT INTO <some_table> (id, text_field)
VALUES ( <id_value>, '<text_field_value>')
RETURNING *;
COMMIT;
Run Code Online (Sandbox Code Playgroud)
现在,INSERT可以看到DELETE.
| 归档时间: |
|
| 查看次数: |
3161 次 |
| 最近记录: |