【PostgreSQL-9.6.3】触发器实例

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

原文地址:https://www.cnblogs.com/NextAction/p/7385002.html