【发布时间】:2014-09-03 17:36:49
【问题描述】:
这里是 Postgres 8.4。想象一下this code snippet from 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;
如果我们想做一些事情,比如登录自定义表,这些异常:
-- 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;
它不会起作用,因为我们在 RAISE EXCEPTION 调用之前放置的任何内容都被 RAISE EXCEPTION 回滚所撤消,即我们创建的 my_log_table 行将在调用 RAISE EXCEPTION 时立即被删除。
完成这样的事情的最佳方法是什么?也许捕捉到我们的自定义异常?
关闭回滚@TRIGGER 不是一个选项,我需要它。
【问题讨论】:
-
你真正想要的是一个子事务(大致相当于 Oracle 的
pragma autonomous。不幸的是,这仍然只是一个提议,还没有实现(Postgres 9.3)。你可以检查不过,这个post 详细说明了一个常见的解决方法。 -
这可能行得通,虽然我感觉在这种特殊情况下就像用大锤敲碎坚果:)
-
当您从任何来源添加长引用时,请同时添加指向该来源的链接。我添加了 Postgres 8.4 手册的链接。
标签: postgresql exception triggers plpgsql