jpp*_*pp1 6 postgresql triggers exception plpgsql
Postgres 8.4 在这里。想象一下来自 Postgres doc 的这个代码片段:
CREATE FUNCTION emp_stamp() RETURNS trigger AS $emp_stamp$
BEGIN
-- Check that empname and salary are given
IF NEW.empname IS NULL THEN
RAISE EXCEPTION 'empname cannot be null';
END IF;
IF NEW.salary IS NULL THEN
RAISE EXCEPTION '% cannot have null salary', NEW.empname;
END IF;
-- Who works for us when she must pay for it?
IF NEW.salary < 0 THEN
RAISE EXCEPTION '% cannot have a negative salary', NEW.empname;
END IF;
-- Remember who changed the payroll when
NEW.last_date := current_timestamp;
NEW.last_user := current_user;
RETURN NEW;
END;
$emp_stamp$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
如果我们想做一些类似登录自定义表的事情,这些异常:
-- Check that empname and salary are given
IF NEW.empname IS NULL THEN
INSERT INTO my_log_table ('User didn't supplied empname')
RAISE EXCEPTION 'empname cannot be null';
END IF;
Run Code Online (Sandbox Code Playgroud)
它不会工作,因为我们在RAISE EXCEPTION调用之前放置的任何内容都被回滚RAISE EXCEPTION暗示,即我们创建的 my_log_table 行将RAISE EXCEPTION在调用后立即被删除。
完成这样的事情的最佳方法是什么?也许捕获我们的自定义异常?
关闭回滚 @ TRIGGER 不是一个选项,我需要它。
您可以捕获错误/捕获异常。
在EXCEPTION块中,您可以执行任何其他操作,例如 INSERT 到另一个表中。之后,您可以重新引发异常以传播出去,但这会将包括 INSERT 在内的整个事务回滚到日志表(除非异常被包装并捕获在外部函数中)。
你可以:
使用像 dblink 调用这样的技巧来模拟一个自治事务,当包装事务回滚时,该事务不会被撤消。有关的:
RAISEaNOTICE或WARNING另外,这也不能由 撤消ROOLBACK。
RAISEEXCEPTION与您自己的文本不同。或者,您可以只取消触发触发器函数的行而不引发异常。交易中的其他一切都正常进行。
假设这是一个触发器,ON UPDATE并且您有另一个具有相同结构的表可以将失败的 INSERT 写入:
CREATE OR REPLACE FUNCTION emp_stamp()
RETURNS trigger AS
$func$
BEGIN
-- Check that empname and salary are given
IF NEW.empname IS NULL THEN
RAISE EXCEPTION 'empname cannot be null';
END IF;
IF ...
RETURN NEW; -- regular end
EXCEPTION WHEN others THEN -- or be more specific
INSERT INTO log_tbl VALUES (NEW.*); -- identical table structure
RETURN NULL; -- cancel row
END
$func$ LANGUAGE plpgsql;Run Code Online (Sandbox Code Playgroud)
请注意,它NEW包含发生异常之前的行的状态,包括同一函数中先前的成功语句。
扳机:
CREATE TRIGGER emp_stamp
BEFORE INSERT OR UPDATE ON tbl
FOR EACH ROW EXECUTE PROCEDURE emp_stamp();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5773 次 |
| 最近记录: |