1. 创建一个触发器,表中的行在任何时候被插入或更新时,当前用户名和时间也会被标记在该行中。并且它会检查雇员的姓名以及薪水。
--创建测试表 CREATE TABLE emp ( empname text, salary integer, last_date timestamp, last_user text ); --创建触发器函数 CREATE FUNCTION emp_stamp() RETURNS trigger AS $emp_stamp$ BEGIN -- 检查 empname 以及 salary 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; -- 谁会倒贴钱为我们工作? IF NEW.salary < 0 THEN RAISE EXCEPTION '% cannot have a negative salary', NEW.empname; END IF; -- 记住谁在什么时候改变了工资单 NEW.last_date := current_timestamp; NEW.last_user := current_user; RETURN NEW; END; $emp_stamp$ LANGUAGE plpgsql; --创建触发器 CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp FOR EACH ROW EXECUTE PROCEDURE emp_stamp(); --测试触发器
test=# insert into emp values ('John'); --salary为空,触发器报错 ERROR: John cannot have null salary CONTEXT: PL/pgSQL function emp_stamp() line 7 at RAISE test=# insert into emp values (null,1200); --empname为空,触发器报错 ERROR: empname cannot be null CONTEXT: PL/pgSQL function emp_stamp() line 4 at RAISE test=# insert into emp values ('John',-200); --salary为负数,触发器报错 ERROR: John cannot have a negative salary CONTEXT: PL/pgSQL function emp_stamp() line 10 at RAISE test=# insert into emp values ('Bob',1200); --成功插入正常数据,并记录了最后操作时间和操作用户 INSERT 0 1 test=# select * from emp; empname | salary | last_date | last_user ---------+--------+----------------------------+----------- Bob | 1200 | 2017-08-09 17:39:23.671957 | postgres (1 row)
2. 用于审计的触发器过程
这个例子触发器保证了在emp表上的任何插入、更新或删除一行的动作都被记录(即审计)在emp_audit表中。当前时间和用户名以及在其上执行的操作类型都会被记录到行中。
--创建测试表 create table emp ( empname text not null, salary integer ); --创建审计表 create table emp_audit( operation char(1) not null, stamp timestamp not null, userid text not null, empname text not null, salary integer ); --创建触发器函数 create or replace function process_emp_audit() returns trigger as $emp_audit$ begin if (TG_OP = 'DELETE') then insert into emp_audit select 'D',now(),user,old.*; return old; elsif (TG_OP = 'UPDATE') then insert into emp_audit select 'U',now(),user,new.*; return new; elsif (TG_OP = 'INSERT') then insert into emp_audit select 'I',now(),user,new.*; return new; end if; return null; end; $emp_audit$ language plpgsql; --创建触发器 create trigger emp_audit after insert or update or delete on emp for each row execute procedure process_emp_audit(); --测试触发器 test=# insert into emp values ('John',1200); INSERT 0 1 test=# select * from emp_audit; operation | stamp | userid | empname | salary -----------+----------------------------+----------+---------+-------- I | 2017-08-09 18:18:10.189772 | postgres | John | 1200 (1 row)
The End!
2017-08-17