触发器
关键字:
触发器、KES、存储过程
1.触发器概述
触发器(trigger)是用户定义的由事件驱动的特殊过程。一旦定义,所有用户的对应操作均会由服务器自动激活相应的触发器,在DBMS核心层进行集中的完整性控制。触发器类似于约束,但是比约束更加灵活,也可以实施比外键约束、检查约束更为复杂的检查和操作,具有更精细和更强大的数据处理能力。
与存储过程一样,触发器是一个命名的 PL/SQL 单元,它存储在数据库中并且可以重复调用。与存储过程不同的是,触发器可以启用和禁用,但不能显式调用。当触发器被启用时,只要它的触发事件发生,触发器就会触发,也就是说,数据库会自动调用它。当触发器被禁用时,它不会触发。 根据创建对象的不同,KingbaseES将触发器分为DML 触发器和系统触发器两种:
(1)如果触发器是在表或视图上创建的,则触发事件由 DML 语句组成,触发器称为DML 触发器。
(2)如果触发器是在模式或数据库上创建的,那么触发事件由 DDL 或数据库操作语句组成,触发器称为系统触发器。
根据依赖触发对象的不同,KingbaseES将触发器分为表级触发器和事件触发器两种:
(1)表级触发器:又称为“语句级触发器”,它依赖于已存在的表,对特定表的相关操作会引动触发器调用相应的触发器函数。其特征为就算执行多条sql语句,也只会触发一次。
(2)事件级触发器:又称为“行级触发器”,创建语句中包含“FOR EACH ROW”,它依赖于特定的事件。
2.DML触发器
DML 触发器在表或视图上创建,其触发事件由 DML 语句 DELETE、INSERT 和 UPDATE 组成。一个简单的 DML 触发器可以在以下时间点触发:
(1)在触发语句运行之前触发:该触发器称为 BEFORE 语句触发器或语句级 BEFORE 触发器。
(2)触发语句运行后触发:该触发器称为 AFTER 语句触发器或语句级 AFTER 触发器。
(3)在触发语句影响的每一行之前触发:该触发器称为 BEFORE 每行触发器或行级 BEFORE 触发器。
(4)在触发语句影响的每一行之后:触发器称为 AFTER 每行触发器或行级 AFTER 触发器。
除此之外,还有一种常用的触发器——INSTEAD OF DML触发器。该触发器是在非编辑视图或非编辑视图的嵌套表列上创建的 DML 触发器。INSTEAD OF触发器不能是有条件的,它是更新本质上不可更新的视图的唯一方法。设计INSTEAD OF触发器以确定预期的操作并在基础表上执行适当的 DML 操作。触发器始终是INSTEAD OF行级触发器。INSTEAD OF触发器可以读取OLD和NEW值,但不能更改它们。 DML触发器的触发事件可以由多个触发语句组成。当其中一个触发触发器时,触发器可以通过使用下列条件谓词来确定哪一个。
条件谓词 | 条件 |
---|---|
INSERTING | 一个INSERT语句触发了触发器 |
UPDATING | 一个UPDATE语句触发了触发器 |
UPDATING('column') | 影响指定列的UPDATE语句触发了触发器 |
3.触发器示例
CREATE TABLE IF NOT EXISTS a(id int, name text, score number);
CREATE OR REPLACE FUNCTION tri_fun() RETURNS trigger AS $$
BEGIN
CASE
WHEN INSERTING THEN
RAISE NOTICE 'Inserting';
WHEN UPDATING('score') THEN
RAISE NOTICE 'Updating score';
WHEN UPDATING('department_id') THEN
RAISE NOTICE 'Updating department ID';
WHEN DELETING THEN
RAISE NOTICE 'Deleting';
END CASE;
return new;
END;
$$ LANGUAGE PLPGSQL;
--before
CREATE TRUGGER trigger_ 1
BEFORE
INSERT OR
UPDATE OF score, id OR
DELETE
ON a
FOR EACH ROW execute procedure tri_fun();
--after
CREATE TRUGGER trigger _2
AFTER
INSERT OR
UPDATE OF score, id OR
DELETE
ON a
FOR EACH ROW execute procedure tri_fun();
CREATE VIEW instead_view AS select id, name, score from temp_tr1;
CREATE TRUGGER trigger_3
INSTEAD OF INSERT AS
insert into
FOR EACH ROW execute procedure tri_fun();
--语句级触发器
create trigger trigger_ 4
BEFORE
INSERT OR
UPDATE OF score, id OR
DELETE
ON a
execute procedure tri_fun();