|
23.9. 触发器过程PL/pgSQL 可以用于定义触发器过程. 一个触发器过程是用 CREATE FUNCTION 命令 创建的,创建的形式是一个不接受参数并且返回 OPAQUE 类型的函数.请注意该函数即使在 CREATE TRIGGER 声明里 声明为准备接受参数,它也必需声明为无参数 --- 触发器的参数是通过 TG_ARGV 传递的,下面有描述. 在一个 PL/pgSQL 函数当做触发器调用的时候, 系统会在顶层的声明段里自动创建几个特殊变量.有如下这些∶
一个触发器函数必须返回 NULL 或者是 一个与导致触发器运行的表的记录/行完全一样的结构的数据. BEFORE 类的触发器可以返回一个 NULL,发送一个信号给触发器管理器 告诉它忽略对实际行的操作(也就是说,随后的触发器将不再执行,并且不会 对该行产生 INSERT/UPDATE/DELETE动作).如果返回了一个非 NULL 的行, 那么将继续对该行数值进行处理. 请注意,返回一个和原来的 NEW 不同的行数值将修改那个将插入或更新的行. 我们可能用一个值直接代替 NEW 里的某个数值并且 返回之,或者我们也可以构建一个完全新的记录/行再返回. 为 AFTER 的触发器返回的数值将被忽略;我们也可以总是返回一个 NULL 值. 但是一个 AFTER 触发器仍然可以通过抛出一个错误来退出操作. Example 23-1. 一个 PL/pgSQL 触发器过程实例 下面的例子触发器的作用是:任何时候表中插入或更新了行, 当前的用户名和时间都记录入行中. 并且它保证给出了雇员名称并且薪水是一个正数. CREATE TABLE emp ( empname text, salary INTEGER, last_date TIMESTAMP, last_user text ); CREATE FUNCTION emp_stamp () RETURNS OPAQUE AS ' BEGIN -- 检查是否给出了 empname 和 salary IF NEW.empname ISNULL THEN RAISE EXCEPTION ''empname cannot be NULL value''; END IF; IF NEW.salary ISNULL THEN RAISE EXCEPTION ''% cannot have NULL salary'', NEW.empname; END IF; -- 我们必须付帐给谁? IF NEW.salary < 0 THEN RAISE EXCEPTION ''% cannot have a negative salary'', NEW.empname; END IF; -- 记住何时何人的薪水被修改了 NEW.last_date := ''now''; NEW.last_user := current_user; RETURN NEW; END; ' LANGUAGE 'plpgsql'; CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp FOR EACH ROW EXECUTE PROCEDURE emp_stamp();
|