PostgreSQL - Добавление исключения к процедуре завершается неудачно: недействительное завершение транзакции - PullRequest
0 голосов
/ 23 февраля 2020

В следующем посте описывается ошибка при попытке использовать коммит и исключение в одном и том же блоке BEGIN .. END:

Может ли Postgres коммит существовать в процедуре, имеющей блок исключения?

Может ли Postgres Фиксация существовать в процедуре, имеющей исключительный блок?

Предоставляет обходной путь, который разделяет блок на новую подпрограмму BEGIN .. END блокирует и выводит COMMIT за пределы подблока.

Это разумный обходной вариант для этого варианта использования, однако он не будет работать при наличии вложенных процедур. Рассмотрим следующий пример (PL / pg SQL):

DROP TABLE testdb.demo;
CREATE TABLE testdb.demo (id numeric(10), msg varchar(100));

CREATE OR REPLACE PROCEDURE testdb.main_proc (v_id int DEFAULT 0)
 LANGUAGE plpgsql
AS $procedure$
DECLARE
    l_context varchar(1000);
BEGIN
    RAISE NOTICE '2';
    INSERT INTO testdb.demo values (3, 'MAIN_PROC');
    call testdb.sub_proc(v_id);
    INSERT INTO testdb.demo values (6, 'MAIN_PROC');
    RAISE NOTICE '3';

    exception when others then 
        RAISE INFO 'Error Name: %', SQLERRM;
        RAISE INFO 'Error State: %', SQLSTATE;
        GET STACKED DIAGNOSTICS l_context = PG_EXCEPTION_CONTEXT;
        RAISE INFO 'Error Context:%', l_context; 


END;
$procedure$
;

CREATE OR REPLACE PROCEDURE testdb.sub_proc(v_id int DEFAULT 0)
 LANGUAGE plpgsql
AS $procedure$
DECLARE
BEGIN
    INSERT INTO testdb.demo values (4, 'SUB_PROC');
    commit;
    INSERT INTO testdb.demo values (5, 'SUB_PROC');
END;
$procedure$
;

Приведенный выше код создает:

  1. Таблица testdb.demo;
  2. Процедура testdb. main_pro c.
  3. Процедура testdb.sub_pro c.

Теперь при вызове testdb.main_pro c произойдет сбой:

postgres=> call testdb.main_proc(100);
NOTICE:  2
INFO:  Error Name: invalid transaction termination
INFO:  Error State: 2D000
INFO:  Error Context:PL/pgSQL function testdb.sub_proc(integer) line 5 at COMMIT
SQL statement "CALL testdb.sub_proc(v_id)"
PL/pgSQL function testdb.main_proc(integer) line 7 at CALL
CALL

Комментирование части исключения внутри testdb.main_pro c завершится без ошибок. Как я могу использовать COMMIT во вложенных процедурах и по-прежнему использовать исключения? Пожалуйста, сообщите,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...