4.5 触发器
触发器(Trigger)是由事件自动触发执行的一种特殊的存储过程,触发事件可以是对一个表进行INSERT、UPDATE、DELETE等操作。
触发器经常用于加强数据的完整性约束和业务规则上的约束等。
4.5.1 创建触发器
创建语法:
CREATE [ CONSTRAINT ] TRIGGER name { BEFORE | AFTER | INSTEAD OF } { event [ OR ... ] } ON table_name [ FROM referenced_table_name ] { NOT DEFERRABLE | [ DEFERRABLE ] { INITIALLY IMMEDIATE | INITIALLY DEFERRED } } [ FOR [ EACH ] { ROW | STATEMENT } ] [ WHEN ( condition ) ] EXECUTE PROCEDURE function_name ( arguments )创建触发器的步骤:
先为触发器建一个执行函数,此函数的返回类型为触发器类型
然后建一个触发器
举例:
创建两张表:学生表 + 成绩表
CREATE TABLE student( student_no int primary key, student_name varchar(40), age int ); CREATE TABLE score ( student_no int, chinese_score int, math_score int, test_date date );规则:删除学生表的学生信息之后,自动删除成绩表中的数据
先创建触发器执行函数
CREATE OR REPLACE FUNCTION student_delete_trigger() RETURNS TRIGGER AS $$ BEGIN DELETE FROM score WHERE student_no = OLD.student_no; RETURN OLD; END; $$ LANGUAGE plpgsql;创建触发器
CREATE TRIGGER delete_student_trigger AFTER DELETE ON student FOR EACH ROW EXECUTE PROCEDURE student_delete_trigger ();
4.5.2 语句级触发器与行级触发器
语句级触发器:执行每个SQL语句时只执行一次
行级触发器:行级触发器是执行每行SQL语句都会执行一次
举例:对student表的更新情况做日志记录
创建表:
CREATE TABLE log_student( update_time timestamp, --操作的时间 db_user varchar(40), --操作的数据库用户名 opr_type varchar(6) --操作类型:insert、delete、update );创建记录日志触发器
CREATE FUNCTION log_student_trigger () RETURNS trigger AS $$ BEGIN INSERT INTO log_student values(now(), user, TG_OP); RETURN NULL; END; $$ LANGUAGE "plpgsql";创建一个语句级触发器
CREATE TRIGGER log_student_trigger AFTER INSERT OR DELETE OR UPDATE ON student FOR STATEMENT EXECUTE PROCEDURE log_student_trigger ();备注:如果一条语句包含多个操作,那么值记录一次
创建一个行级触发器
CREATE TRIGGER log_student_trigger2 AFTER INSERT OR DELETE OR UPDATE ON student FOR ROW EXECUTE PROCEDURE log_student_trigger ();备注:一条语句有多个操作,每个操作都会记录
4.5.3 BEFORE触发器与AFTER触发器
BEFORE触发器是在操作之前触发的,包括语句级与行级
AFTER触发器在操作之后触发的,包括语句级与行级
4.5.4 删除触发器
语法:
DROP TRIGGER [ IF EXISTS ] name ON table [ CASCADE | RESTRICT ];备注:
IF EXISTS:如果触发器不存在,那么发出一个notice而不是抛出一个错误CASCADE:级联删除依赖此触发器的对象RESTRICT:默认值,有依赖对象存在就拒绝删除删除触发器时,触发器函数不会被删除,删除表时,表上的触发器也会被删除
4.5.5 触发器的行为
触发器函数有返回值,语句级应该返回null,必须显示地在触发器函数中写
RETURN NULL,没写会报错
4.5.6 触发器函数中的特殊变量
NEW:该变量为INSERT/UPDATE操作触发的行级触发器中存储新的数据行,数据类型是“RECORD”。在语句级别的触发器中此变量未分配,DELETE操作触发的行级触发器中此变量也未分配OLD:该变量为UPDATE/DELETE操作触发的行级触发器中存储原有的数据行,数据类型是“RECORD”。在语句级别的触发器中此变量未分配,INSERT操作触发的行级触发器中此变量也未分配TG_NAME:数据类型是name类型,该变量包含实际触发的触发器名TG_WHEN:内容为“BEFORE”或“AFTER”字符串用于指定是BEFORE触发器还是AFTER触发器TG_LEVEL:内容为“ROW”或“STATEMENT”字符串用于指定是语句级触发器还是行级触发器TG_OP:内容为“INSERT”“UPDATE”“DELETE”“TRUNCATE”之一的字符串,用于指定DML语句的类型TG_RELID:触发器所在表的OIDTG_RELNAME:触发器所在表的名称,该变量即将[…]TG_ARGV[]:为text类型的数组;是CREATE TRIGGER语句中的参数
最后更新于