千家信息网

数据库:触发器

发表于:2024-11-11 作者:千家信息网编辑
千家信息网最后更新 2024年11月11日,触发器的概念:是用户定义在关系表上的一类有事件驱动的特殊过程。一旦定义,任何对表的增删改操作均有服务器自动激活相应的触发器,在DBMS核心层进行集中的完整性控制。类似于约束,但比约束更灵活。触发器的分
千家信息网最后更新 2024年11月11日数据库:触发器

触发器的概念:

是用户定义在关系表上的一类有事件驱动的特殊过程。一旦定义,任何对表的增删改操作均有服务器自动激活相应的触发器,在DBMS核心层进行集中的完整性控制。类似于约束,但比约束更灵活。


触发器的分类:

DML触发器:DML(Data Manipulation Language)触发器是当数据库服务器中发生数据操作语言事件时执行的存储过程。DML触发器又分为两类:After触发器和Instead Of触发器

DDL触发器:DDL触发器是在响应数据定义语言(Data Definition Language)事件时执行的存储过程。DDL触发器一般用于执行数据库中管理任务。如审核和规范数据库操作、防止数据库表结构被修改等。

After触发器:这类触发器是在记录已经改变完之后(after),才会被激活执行,它主要是用于记录变更后的处理或检查,一旦发现错误,也可以用Rollback Transaction语句来回滚本次的操作。

Instead Of触发器:这类触发器一般是用来取代原本的操作,在记录变更之前发生的,它并不去执行原来SQL语句里的操作(Insert、Update、Delete),而去执行触发器本身所定义的操作。

在SQL Server里,每个DML触发器都分配有两个特殊的表,一个是Inserted表,一个是Deleted表。它们两个存在于数据库服务器的内存中,是由系统管理的逻辑表,是两个临时表,而不是真正存储在数据库中的物理表。用户对这两个表只有读取的权限,没有修改的权限。

这两个表的结构(主外键、字段、数据类型等)与触发器所在数据表的结构是完全一致的,当触发器的工作完成之后,这两个表也将会从内存中删除。

定义触发器:

使用CREATE TRIGGER命令建立触发器,其一般格式为:

CREATE TRIGCER <触发器名>| BEFORE| AFTER| <触发事件>ON<表名>FOR EACH | ROW| STATEMENT|{ WHEN <触发条件>}<触发动作体>

1.触发器名:可包含模式名,也可不包含,同一模式下,触发器名必须是唯一的;并且触发器名和<表名>

必须在同一模式下。


2.表名:表数据发生变化是,激活定义在该表上相应<触发事件>的触发器,也称触发器的目标表。


3。触发事件:可以是INSERT ,DELETE .UPDATE,也可以是这几个事件的组合。指明修改哪些列时触发器

组合,可以是几个事件的组合并且可以附加OF <触发列>。


4.触发器类型:行级触发器(FOR EACH ROW),语句级触发器(FOR EACH STATEMENT).


5.触发条件:被激活时,只有当触发条件为真时触发动作提才执行,如果省略WHEN,则触发动作体在触

发器激活后立即执行


6.触发动作体:是一个匿名PL/SQL过程块,也可以是对已创建存储过程的调用。

如果是行级触发器,2中情况下都可以使用NEW/OLD引用,UPDATE/INSER事件之后的新值和UPDATE/DELETE事件之前的旧值。如果是语句级触发器,则不能在触发动作体中使用NEW/OLD引用。


下面看一下例子:

定义一个BEFORE行级触发器,为教师表Teacher定义完整性规则"教授的工资不得低于4000元,如果低于,就自动改为4000"

CREATE TRLGGER Insert_Or_Updata_Sal   /*在教师表Teacher上定义触发器*/    BEFORE INSERT OR UPDATE ON Teacher     FOR EACH ROW    AS BEGIN        IF(new.Job = '教授') AND (new.Sal < 4000) THEN            new.Sal : = 4000;        END IF    END;


定义AFTER 行级触发器,当教师表Teacher的工资发生变化后自动在工资变化表Sal_log中增加一条相应记录

CREATE TRLGGER Insert_Sal       AFTER INSERT ON Teacher     FOR EACH ROW    AS BEGIN        INSERT INTO Sal_log VALUES(            new.Eno,new.Sal,CURRENT_USER,CURRENT_TIMESTAMP);        END;        CREATE TRLGGER Update_Sal       AFTER UPDATE ON Teacher     FOR EACH ROW    AS BEGIN        IF(new.Sal <> old.Sal) THEN INSERT INTO Sal_log VALUES(            new.Eno,new.Sal,CURRENT_USER,CURRENT_TIMESTAMP);        END IF;    END;

激活触发器:

执行表上的BEFORE触发器;

激活触发器的SQL语句;

执行该表上的AFTER触发器。

删除触发器:

DROP TRIGGER<触发器名> ON <表名>;

0