PostgreSQL 支持触发器功能,触发器与表或者视图进行关联,当表或者视图上的某个事件发生时,指定的触发器函数将被调用。
触发器语法:
CREATE [ CONSTRAINT ] TRIGGER name { BEFORE | AFTER | INSTEAD OF } { event [ OR ... ] }
ON table_name
[ FROM referenced_table_name ]
[ NOT DEFERRABLE | [ DEFERRABLE ] [ INITIALLY IMMEDIATE | INITIALLY DEFERRED ] ]
[ REFERENCING { { OLD | NEW } TABLE [ AS ] transition_relation_name } [ ... ] ]
[ FOR [ EACH ] { ROW | STATEMENT } ]
[ WHEN ( condition ) ]
EXECUTE { FUNCTION | PROCEDURE } function_name ( arguments )
触发器支持的 event 事件类型包含:
- insert
- update
- delete
- truncate
触发器的触发时机包含:
- before,在事件执行之前触发
- after,在事件执行之后触发
- instead of
1. 行级触发器
下面通过一个示例来了解触发的创建以及使用,创建一个触发器,实现表 t1 的 insert 操作同步到 t2。
(1)创建表 t1、t2
create table t1(id int, name text);
create table t2(id int, name text);
(2)创建函数,实现 t1 的 insert 操作同步到 t2
create or replace function myfunc_insert() returns trigger AS $mytable$
begin
insert into t2(id, name) values (new.id, new.name);
return new;
end;
$mytable$ LANGUAGE plpgsql;
(3)创建触发器
-- after 类型
create trigger mytrigger after insert on t1 for each row execute function myfunc_insert();
-- before 类型
create trigger mytrigger before insert on t1 for each row execute function myfunc_insert();
2. 语句级触发器
创建 log 表,记录语句执行日志:
create table mylog(id serial, ts timestamp, op text);
创建语句级触发器调用的函数:
create or replace function myfunc_insert() returns trigger AS $mytable$
begin
insert into mylog(ts, op) values (now(), TG_OP);
return new;
end;
$mytable$ LANGUAGE plpgsql;
创建语句级触发器:
create trigger mytrigger2
after insert on t1
referencing new table as inserted
for each statement
execute function myfunc_insert();
3. 触发器的内置变量
触发器在被调用时,系统会自动传递一些数据给它,这些数据包括触发触发器的事件类型(例如INSERT或UPDATE),对于行级触发器,还包括NEW数据行(对于INSERT和UPDATE触发器)和OLD数据行(对于UPDATE和DELETE触发器)。每种可以用来书写触发器函数的语言都提供了取这些数据的方法。
当一个 PL/pgSQL 函数作为一个触发器被调用时,系统自动在最外层的块创建一些特殊的变量。这些变量分别是:
- NEW,数据类型是 RECORD。对于行级触发器,它存有 INSERT 或 UPDATE 操作产生的新的数据行。对于语句级触发器,它的值是 NULL。
- OLD,数据类型是 RECORD。对于行级触发器,它存有被 UPDATE 或 DELETE 操作修改或删除的旧的数据行。对于语句级触发器,它的值是 NULL。
- TG_NAME,数据类型是 name,它保存实际被调用的触发器的名字。
- TG_WHEN,数据类型是 text,根据触发器定义信息的不同,它的值是 BEFORE 或 AFTER。
- TG_LEVEL,数据类型是 text,根据触发器定义信息的不同,它的值是 ROW 或 STATEMENT。
- TG_OP,数据类型是 text,它的值是 INSERT、UPDATE 或 DELETE,表示触发触发器的操作类型。
- TG_RELID,数据类型是 oid,表示触发器作用的表的 oid。
- TG_RELNAME,数据类型是 name,表示触发器作用的表的名字。它与下面的变量 TG_TABLE_NAME的作用是一样的。
- TG_TABLE_NAME,数据类型是 name,表示触发器作用的表的名字。
- TG_TABLE_SCHEMA,数据类型是 name,表示触发器作用的表所在的模式。
- TG_NARGS,数据类型是 integer,表示 CREATE TRIGGER 命令传给触发器过程的参数的个数。
- TG_ARGV[],数据类型是 text 类型的数组。表示 CREATE TRIGGER 命令传给触发器过程的所有参数。下标从0开始。TG_ARGV[0]表示第一个参数,TG_ARGV[1]表示第二个参数,以此类推。如果下标小于0或大于等于 tg_nargs,将会返回一个空值。
4. 查询所有的触发器
select * from pg_trigger;
-- 查询触发器的定义
select pg_get_triggerdef(oid) from pg_trigger where tgname='mytrigger';
5. 删除触发器
drop trigger mytrigger on t1;
参考资料:
https://www.postgresql.org/docs/13/sql-createtrigger.html