触发器

本章节主要介绍在 DM 数据库中触发器的使用。

一、适用场景

软件 版本
操作系统 Redhat 7 及以上版本
DM 数据库 DM 8.0 及以上版本
CPU 架构 x86、ARM、龙芯、飞腾等国内外主流 CPU

二、操作方法

2.1 表级触发器

表级触发器的触发动作是三种数据操作命令,即 INSERT、DELETEUPDATE 操作。

  • 创建触发器,如下所示:
CREATE  OR  REPLACE TRIGGER TRG_NAME   [WITH ENCRYPTION]
BEFORE|AFTER|INSTEAD OF 
INSERT OR DELETE OR UPDATE [OF 列名]
ON TABLE_NAME 
FOR EACH ROW  [WHEN 条件] --行级触发器中,此子句一定不能省略
BEGIN
 PRINT 'INSERT OR DELETE OR UPDATE OPERATION ON TABLE_NAME';--要执行的SQL。
 END;

以下“[]”内容为可选项:

  1. [WITH ENCRYPTION]:对数据进行加密,加密以后,无法看到触发器里的 sql 语句内容。
  2. UPDATE [OF 列名]:如果指定了 UPDATE 命令,还可以进一步指定当表中的哪个列受到 UPDATE 命令的影响时激发该触发器。
  3. FOR EACH ROW [WHEN 条件] :对于元组级触发器,可以用一个 WHEN 子句来限制针对当前记录是否执行该触发器。WHEN 子句包含一条布尔表达式,当它的值为 TRUE 时,执行触发器;否则,跳过该触发器。

行级触发器,对触发命令所影响的每一条记录都激发一次。

CREATE OR REPLACE TRIGGER TRG_NAME
AFTER INSERT OR DELETE OR UPDATE ON TABLE_NAME
FOR EACH STATEMENT -- 语句级:此子句可省略
BEGIN
 PRINT 'INSERT OR DELETE OR UPDATE OPERATION ON TABLE_NAME';--要执行的SQL
END;

语句级触发器,对每个触发命令执行一次。

  • 创建 BEFORE 触发器,该触发器在插入一条记录前,将记录中第一列 READER_ID 的值加 1。如下所示:
--进入数据库 OTHER 模式
SET SCHEMA OTHER;
--创建 BEFORE 触发器
CREATE OR REPLACE TRIGGER TRG_INS_BEFORE
BEFORE INSERT ON OTHER.READER
FOR EACH ROW
BEGIN
:NEW.READER_ID:=:NEW.READER_ID+1;
END;

插入记录前:

image.png

插入一条记录:

insert into OTHER.READER(READER_ID, NAME, AGE, GENDER, MAJOR)
VALUES(13, 'test', 20, 'F', 'History');

COMMIT;

插入记录后:

image.png

插入的 READER_ID 值为 13 ,插入时触发:NEW.READER_ID:=:NEW.READER_ID+1,提交的 READER_ID 值为 14。

  • 创建 AFTER 触发器,该触发器在插入一条记录后,将插入的值以及操作类型记录到用于审计的表 T_TEMP 中。如下所示:
CREATE TABLE T_TEMP(C1 INT,C2 CHAR(20));

CREATE OR REPLACE TRIGGER TRG_INS_AFTER
AFTER INSERT ON OTHER.READER
FOR EACH ROW
BEGIN
 INSERT INTO T_TEMP VALUES(:NEW.READER_ID, 'INSERT ON READER');
END;

插入一条记录:

insert into OTHER.READER(READER_ID, NAME, AGE, GENDER, MAJOR)
VALUES(15, 'test1', 22, 'F', 'Computer');

COMMIT;

插入记录后:

image.png

提交后插入数据到表 T_TEMP 中。

  • 创建 INSTEAD OF 触发器,该触发器在动作触发的时候,替换原始操作,INSTEAD OF 允许建立在视图上,并且只支持行级触发。如下所示:
--创建视图 v1
create table t1(a int,b int);
insert into t1 values(10,10);
insert into t1 values(11,11);
create view v1 as select * from t1;
--在视图 v1 上创建 INSTEAD OF 触发器。
CREATE OR REPLACE TRIGGER tri1
INSTEAD OF UPDATE ON v1
BEGIN
 insert into t1 values(111,111); --替换动作
END;

执行 UPDATE 动作:

update v1 set a=100 where a=10;

查询结果:

image.png

更新操作并没有成功,而是被触发器中的替换动作替换了。

2.2 时间触发器

时间触发器属于一种特殊的事件触发器,可以定义一些有规律性执行的、定点执行的任务。

  • 创建时间触发器,在屏幕上每隔一分钟输出一行 HELLO WORLD。如下所示:
CREATE OR REPLACE TRIGGER timer2
AFTER TIMER on database
for each 1 day for each 1 minute
BEGIN
print 'HELLO WORLD';
END;

时间触发器的最低时间频率精确到分钟级,定义很灵活,完全可以实现数据库中的代理功能,只要通过定义一个相应的时间触发器即可。在触发器体中定义要做的工作,可以定义操作的包括执行一段 SQL 语句、执行数据库备份、执行重组 B 树、执行更新统计信息、执行数据迁移 (DTS)。

2.3 触发器管理

  • 每个触发器创建成功后都自动处于允许状态 (ENABLE),当不想被触发,但是又不想删除这个触发器。这时,可将其设置关闭触发器 (DISABLE)。
--关闭触发器
ALTER TRIGGER OTHER.TRG_INS_AFTER DISABLE;
--打开触发器
ALTER TRIGGER OTHER.TRG_INS_AFTER ENABLE;
  • 触发器删除
DROP TRIGGER OTHER.TRG_INS_AFTER;
  • 触发器查看
--查看当前数据库的全部触发器
SELECT * FROM DBA_TRIGGERS;
--查看当前用户有权限访问的触发器
SELECT * FROM ALL_TRIGGERS;
--查看示当前用户所拥有的触发器
SELECT * FROM USER_TRIGGERS;

输出结果:

image.png

注意

1.<触发器名> 是触发器的名称,它不能与模式内的其他模式级对象同名。
2.可以使用 OR REPLACE 选项来替换一个触发器,但是要注意被替换的触发器的触发表不能改变。如果要在同一模式内不同的表上重新创建一个同名的触发器,则必须先删除该触发器,然后再创建。
3.INSTEAD OF 触发器仅允许建立在视图上,并且只支持行级触发。
4.表级触发器不支持跨模式,即 <触发器名> 必须和 <触发表名>、<触发视图名> 的模式名一致。
5.水平分区子表、HUGE 表不支持表级触发器。
6.同类触发器的激发顺序没有明确的定义。如果顺序非常重要的话,应该把所有的操作组合在一个触发器中。
7.在 DM 的数据守护环境下,备库上定义的触发器是不会被触发的。

三、参考文献

更多 SQL 语言使用说明,请参考《DM8_SQL 语言使用手册》,手册位于数据库安装路径 /dmdbms/doc 文件夹下。如有其他问题,请在社区内咨询。

微信扫码
分享文档
扫一扫
联系客服