我正在维护一个 psql
脚本,当其中任何部分失败时,我通常希望立即中止它,并返回非零退出代码。
因此,我考虑将以下语句之一放置在脚本的开头:
\set ON_ERROR_STOP on
在开始时,或者指导用户使用脚本运行
psql -v ON_ERROR_STOP=on -f my_script.sql
但是,脚本中有一部分是故意失败的(并且被回滚)。由于该脚本是用于教育和演示目的,并且该部分演示了约束条件实际上按照应有的方式工作(通过使随后违反约束条件的插入操作失败),因此我无法真正“修复”那部分使其不会失败,所以如何保存和恢复ON_ERROR_STOP的值?中的被接受答案并不能解决我的问题。
因此,在那部分之前禁用
ON_ERROR_STOP
,在该部分之后恢复设置。如果我知道在一般情况下启用了ON_ERROR_STOP
,那么这很容易实现:\set ON_ERROR_STOP off
BEGIN;
-- [ part of the script that purposfully fails ]
ROLLBACK;
\set ON_ERROR_STOP on
或者
\unset ON_ERROR_STOP
BEGIN;
-- [ part of the script that purposefully fails ]
ROLLBACK;
\set ON_ERROR_STOP on
然而,这会盲目地重新启用
ON_ERROR_STOP
,无论之前是否已启用。\set previous_ON_ERROR_STOP :ON_ERROR_STOP
\unset ON_ERROR_STOP
BEGIN;
-- [ part of the script that purposefully fails ]
ROLLBACK;
\set ON_ERROR_STOP :previous_ON_ERROR_STOP
如果之前明确禁用了 ON_ERROR_STOP
(例如设置为 off
),则可以正常工作,但如果未设置(因此只是隐式禁用),则会失败。
我希望脚本仍然向后兼容 PostgreSQL 9.x,因此我目前无法使用 PostgreSQL 10 中引入的 \if
元命令。
off
。虽然这对于 9.x 没有帮助,但重点是如果您针对 PG10,则不需要\if
测试。而且,您链接的答案在该版本中已过时。 - Daniel Vérité