触发器(TRIGGER)定义为当某些与数据库有关的事件发生时,数据库应该采取的操作。这些事件包括全局对象、数据库下某个模式、模式下某个基表上的 INSERT、DELETE 和 UPDATE 操作。触发器与存储模块类似,都是在服务器上保存并执行的一段 DMSQL 程序语句。不同的是:存储模块必须被显式地调用执行,而触发器是在相关的事件发生时由服务器自动地隐式地激发。触发器是激发它们的语句的一个组成部分,即直到一个语句激发的所有触发器执行完成之后该语句才结束,而其中任何一个触发器执行的失败都将导致该语句的失败,触发器所做的任何工作都属于激发该触发器的语句。
一、表级触发器
表级触发器都是基于表中数据的触发器,它通过针对相应表对象的插入/删除/修改等DML语句触发。
表级触发器的语法格式:
CREATE [OR REPLACE] TRIGGER [<模式名>.]<触发器名> [WITH ENCRYPTION]
<触发限制描述> [REFERENCING ][REFERENCING <trig_referencing_list>][FOR EACH {ROW | STATEMENT}][WHEN (<条件表达式>)]<触发器体>
<trig_referencing_list>::= <referencing_1>|<referencing_2>
<referencing_1>::=OLD [ROW] [AS] <引用变量名> [ NEW [ROW] [AS] <引用变量名>]
<referencing_2>::=NEW [ROW] [AS] <引用变量名>
<触发限制描述>::=<触发限制描述1> | <触发限制描述2>
<触发限制描述1>::= <BEFORE|AFTER> <触发事件列表> [LOCAL] ON <触发表名>
<触发限制描述2>::= INSTEAD OF <触发事件列表> [LOCAL] ON <触发视图名>
<触发表名>::=[<模式名>.]<基表名>
<触发事件>::=INSERT|DELETE|{UPDATE|{UPDATE OF<触发列清单>}}
<触发事件列表>::=<触发事件> | {<触发事件列表> OR <触发事件>}
激发表触发器的触发动作是三种数据操作命令,即 INSERT、DELETE 和 UPDATE 操作。在触发器定义语句中用关键字 INSERT、DELETE 和 UPDATE 指明构成一个触发器事件的数据操作的类型,其中 UPDATE 触发器会依赖于所修改的列,在定义中可通过 UPDATE OF < 触发列清单 > 的形式来指定所修改的列,< 触发列清单 > 指定的字段数不能超过 128 个。
例如创建一个表触发器:
SET SCHEMA STUDENT;
CREATE OR REPLACE TRIGGER TRG_STU
AFTER UPDATE||INSERT OF NAME,GRADE ON STUDENT.STUDENT
BEGIN
PRINT 'UPDATE||INSERT OPERATION ON COLUMNS NAME OR GRADE OF STUDENT';
END;
SET SCHEMA SYSDBA;
当对表 STUDENT进行UPDATE||INSERT操作时,并且UPDATE||INSERT的列中有NAME 或 GRADE 时,TRG_STU触发器将被激发。
对表STUDENT 的 INSERT 和 DELETE 操作都会激发触发器TRG_STU。
二、事件触发器
事件触发器是对数据库对象操作引起的数据库的触发。
事件触发的语法格式:
CREATE [OR REPLACE] TRIGGER [<模式名>.]<触发器名> [WITH ENCRYPTION] <BEFORE| AFTER> <触发事件子句> ON <触发对象名>[WHEN <条件表达式>]<触发器体> <触发事件子句>:=<DDL事件子句>| <系统事件子句> <DDL事件子句>:=<DDL事件>{OR <DDL事件>} <DDL事件>:=DDL|<CREATE|ALTER|DROP|GRANT|REVOKE|TRUNCATE|COMMENT> <系统事件子句>:=<系统事件>{OR <系统事件>} <系统事件>:= LOGIN|LOGOUT|SERERR|<BACKUP DATABASE>|<RESTORE DATABASE>|AUDIT|NOAUDIT|TIMER|STARTUP|SHUTDOWN <触发对象名>:=[<模式名>.]SCHEMA| DATABASE
对于事件触发器,所有的事件信息都通过伪变量 :EVENTINFO 来取得。
事件操作说明如下:
1)CREATE:添加新的数据库对象(包括用户、基表、视图等)到数据字典时触发;
2)ALTER:只要 ALTER 修改了数据字典中的数据对象(包括用户、基表、视图等),就激活触发器
3)DROP:从数据字典删除数据库对象(包括用户、登录、基表、视图等)时触发;
4)GRANT:执行 GRANT 命令时触发;
5)REVOKE:执行 REVOKE 命令时触发;
6)TRUNCATE:执行 TRUNCATE 命令时触发;
7)LOGIN/LOGON:登录时触发;
8)LOGOUT/LOGOFF:退出时触发;
9)BACKUP DATABASE:备份数据库时触发;
10)RESTORE DATABASE:还原数据库时触发;
11)SERERR:只要服务器记录了错误消息就触发;
12)COMMENT ON DATABASE/SCHEMA:执行 COMMENT 命令时触发;
13)AUDIT:进行审计时触发(用于收集,处理审计信息);
14)NOAUDIT:不审计时触发;
15)TIMER:定时触发。见下文时间触发器;
16)STARTUP:服务器启动后触发,只能 AFTER STARTUP。
例如:
当登录时,服务器就会打印出SUCCESS LOGIN:
create or replace trigger login_trigger
after LOGIN on database
begin print'SUCCESS LOGIN';
end;
三、时间触发器
时间触发器是一种特殊的事件触发器,它使得用户可以定义一些有规律性执行的、定点执行的任务。
时间触发器的语法格式:
CREATE [OR REPLACE] TRIGGER [<模式名>.]<触发器名>[WITH ENCRYPTION] AFTER TIMER ON DATABASE[EXECUTE AT <触发的RAFT组名>] <{FOR ONCE AT DATETIME [<时间表达式>]<exec_ep_seqno>}|{{<month_rate>|<week_rate>|<day_rate>} {<once_in_day>|<times_in_day>}{<during_date>}<exec_ep_seqno>}> [WHEN <条件表达式>] <触发器体> <month_rate>:= {FOR EACH <整型变量> MONTH {<day_in_month>}}| {FOR EACH <整型变量> MONTH { <day_in_month_week>}} <day_in_month>:= DAY <整型变量> <day_in_month_week>:= {DAY <整型变量> OF WEEK<整型变量>}|{DAY <整型变量> OF WEEK LAST} <week_rate>:=FOR EACH <整型变量> WEEK {<day_of_week_list>} <day_of_week_list >:= {<整型变量>}|{, <整型变量>} <day_rate>: =FOR EACH <整型变量> DAY <once_in_day >:= AT TIME <时间表达式> <times_in_day >:={ <duaring_time> } FOR EACH <整型变量> <freq_sub_type> <freq_sub_type>:= MINUTE | SECOND <duaring_time>:={NULL}|{FROM TIME <时间表达式>}|{FROM TIME <时间表达式> TO TIME <时间表达式>} <duaring_date>:={NULL}|{FROM DATETIME <日期时间表达式>}|{FROM DATETIME <日期时间表达式> TO DATETIME <日期时间表达式>} <exec_ep_seqno>:=EXECUTE AT <DMDSC节点号>
时间触发器的最低时间频率精确到秒级,定义很灵活,完全可以实现数据库中的代理功能,只要通过定义一个相应的时间触发器即可。在触发器体中定义要做的工作,可以定义操作的包括执行一段 SQL 语句、执行数据库备份、执行重组 B 树、执行更新统计信息、执行数据迁移(DTS)。
例如屏幕上每隔一分钟输出一行“HELLO WORLD”的时间触发器:
CREATE OR REPLACE TRIGGER timer2
AFTER TIMER on database
for each 1 day for each 1 minute
BEGIN
print 'HELLO WORLD';
END;
四、禁止或者启用触发器
ALTER TRIGGER [<模式名>.]<触发器名> <DISABLE | ENABLE>;
五、删除触发器
DROP TRIGGER [<模式名>.]<触发器名>;
达梦数据库 - 新一代大型通用关系型数据库 | 达梦在线服务平台