我如何在我的postgres函数中实现提交和回滚,代码如下。回滚在例外块中使用
CREATE OR REPLACE FUNCTION test () RETURNS VOID AS $body$
DECLARE
test_var smallint;
BEGIN
FOR abc IN
(SELECT DISTINCT ID
FROM plantab abc
JOIN xxx_upl_att xxx_val ON zzz_val.idf_tec = abc.ID
)
LOOP
select * from abc_pk_attribut(abc.ID) into test_var;
select * from abc_pk_champ(abc.ID) into test_var;
select * from abc_pk_valeur(abc.ID) into test_var;
select * from abc_pk_m_att(abc.ID) into test_var;
PERFORM abc_pk_maj_avalorise(abc.ID);
PERFORM abc_pk_maj_ab_attr(abc.ID);
END LOOP;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
raise notice 'program_error';
END;
$body$
LANGUAGE PLPGSQL
SECURITY DEFINER
;
答案 0 :(得分:1)
您不能这样做。 PostgreSQL函数在外部事务内部运行,该外部事务应在外部提交或回滚。当您从SELECT
语句运行函数时,该语句将在隐式事务(在自动提交模式下)或显式事务(在关闭自动提交时)下执行。谁开始了此交易,然后他必须完成交易。
您可以做什么:
您可以引发一个异常-如果未处理此异常,则外部语句必须运行回滚。
您可以使用子句EXCEPTION WHEN
。然后,将受保护的块与保存点隐式连接。处理任何异常后,引擎将隐式使用ROLLBACK TO savepoint
。
无论如何,该系统与您从MS-SQL或Oracle所了解的系统不同,并且您无法使用您从Oracle知道的某些模式。另一方面-Postgres设计非常简单。
新的PostgreSQL 11具有过程,您可以在其中使用显式的COMMIT
和ROLLBACK
。