Как приостановить ON_ERROR_STOP в PostgreSQL только для части сценария psql? - PullRequest
0 голосов
/ 10 октября 2018

Я поддерживаю сценарий 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.

1 Ответ

0 голосов
/ 10 октября 2018

Я не думаю, что вы можете сделать это.

Однако вы могли бы использовать блок PL / pgSQL, чтобы запустить оператор, перехватить и сообщить об ошибке, примерно так:

DO
$$BEGIN
   INSERT INTO mytab VALUES (...);
EXCEPTION
   WHEN integrity_constraint_violation THEN
      RAISE NOTICE 'Caught error: %', SQLERRM;
END;$$;

Это сообщит об ошибке, но не остановит psql.

...