Я поддерживаю сценарий psql
, который я обычно хочу немедленно прервать с ненулевым кодом завершения, когда какая-либо его часть не работает.
Таким образом, я рассматриваю любое место
\set ON_ERROR_STOP on
в начале или дать пользователям указание запускать сценарий с помощью
psql -v ON_ERROR_STOP=on -f my_script.sql
Однако есть часть сценария, которая намеренно завершается сбоем (и откатывается).Поскольку сценарий предназначен для образовательных и демонстрационных целей, и поскольку эта часть демонстрирует, что CONSTRAINT действительно работает, как и должно (делая последующую ошибку INSERT, нарушающей ограничение), я не могу действительно «исправить» эту часть, чтобы она не потерпела неудачу, поэтомупринят ответ от Как сохранить и восстановить значение 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, поэтому я пока не могу использовать мета-команды \if
, представленные в PostgreSQL 10.