在 Postgres 事务中,如果存在则删除的最佳方法是什么,否则失败?
In a Postgres transaction, what is the best way to delete if exists, and fail otherwise?
在 Postgres 中,我想在事务中执行大量删除和写入操作,但如果要删除的行不存在,我想使事务失败。执行此操作的最佳方法是什么?
使用 PL/pgSQL 代码块(在 FUNCTION
、PROCEDURE
或 DO
语句中)并在 DELETE
未找到时引发异常任何行。您可以使用特殊变量 FOUND
:
DO
$do$
BEGIN
DELETE FROM tbl1 WHERE id = 1;
IF NOT FOUND THEN
RAISE EXCEPTION 'Failed to delete!';
END IF;
INSERT INTO tbl2 (col1) VALUES ('foo');
END
$do$;
引发异常会回滚整个事务。
Note in particular that EXECUTE
changes the output of GET DIAGNOSTICS
, but does not change FOUND
.
参见:
- Dynamic SQL (EXECUTE) as condition for IF statement
如果没有行被删除,这个想法会引发异常:
delete from mytable
where id = 123
and 1/(select count(*) from mytable where id = 123) > 0
这适用于子查询,它应该具有与删除的 where 子句相同的 where 子句,如果没有要删除的匹配行,则返回 0
,这会导致被零除错误将自动使事务失败,导致所有工作回滚。
在 Postgres 中,我想在事务中执行大量删除和写入操作,但如果要删除的行不存在,我想使事务失败。执行此操作的最佳方法是什么?
使用 PL/pgSQL 代码块(在 FUNCTION
、PROCEDURE
或 DO
语句中)并在 DELETE
未找到时引发异常任何行。您可以使用特殊变量 FOUND
:
DO
$do$
BEGIN
DELETE FROM tbl1 WHERE id = 1;
IF NOT FOUND THEN
RAISE EXCEPTION 'Failed to delete!';
END IF;
INSERT INTO tbl2 (col1) VALUES ('foo');
END
$do$;
引发异常会回滚整个事务。
Note in particular that
EXECUTE
changes the output ofGET DIAGNOSTICS
, but does not changeFOUND
.
参见:
- Dynamic SQL (EXECUTE) as condition for IF statement
如果没有行被删除,这个想法会引发异常:
delete from mytable
where id = 123
and 1/(select count(*) from mytable where id = 123) > 0
这适用于子查询,它应该具有与删除的 where 子句相同的 where 子句,如果没有要删除的匹配行,则返回 0
,这会导致被零除错误将自动使事务失败,导致所有工作回滚。