В следующем посте описывается ошибка при попытке использовать коммит и исключение в одном и том же блоке 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$
;
Приведенный выше код создает:
- Таблица testdb.demo;
- Процедура testdb. main_pro c.
- Процедура 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 во вложенных процедурах и по-прежнему использовать исключения? Пожалуйста, сообщите,