有朋友问怎么实现存储过程(本篇特指函数)中的SAVEPOINT,直接调用是不可以的,因为PG不允许事务控制语句出现在存储过程中,但我们还是有办法做到一定程度的模拟。
1、用BEGIN块模拟
随便建个表:
CREATE TABLE a(col1 int);
存储过程如下:
CREATE OR REPLACE FUNCTION ins_t() RETURNS voidAS $$BEGIN INSERT INTO a VALUES(100); BEGIN INSERT INTO a VALUES(200); RAISE 'any error'; EXCEPTION WHEN others THEN null; END;END;$$ LANGUAGE plpgsql;
测试:
flying=# SELECT ins_t(); ins_t-------(1 row)flying=# SELECT * FROM a; col1------ 100(1 row)
可以看到,内嵌BEGIN块中的INSERT操作并没有生效。
2、PL/pgSQL如何实现
块定义在pl_gram.y中,有兴趣可以自己去看,块的执行代码位于 src/pl/plpgsql/src/pl_exec.