目录
触发器的创建
DML触发器的创建
语句级 DML 触发器的创建
创建触发器,当对emp数据表进行添加记录、更新记录和删除记录的时候,判断是否是工作时间段,如果不是工作时间段,不允许执行
在数据表 dept 上创建触发器,当在该表上插入、删除或者更新的时候,记录操作日志
行级 DML 触发器的创建
为 emp 数据表创建一个触发器,当插入新员工的时候,显示新员工的工号和姓名;当更新员工工资的时候,显示每个员工更新前后的工资;当删除员工的时候,显示被删除员工的工号和姓名
创建一个数据表用于存放学生的基本信息,并创建一个序列,然后在表上创建一个触发器,在向表中插入数据的时候,触发所建立的触发器,为学生信息表自动添加主键序列值
Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209645
触发器的创建
触发器的基本语法如下所示。
CREATE OR REPLACE TRIGGER<触发器名>
<触发时间 ><触发事件 > ON<表名 > 视图名 >|< 数据库名 >< 模式名>
[FOR EACH ROW]
[WHEN<条件表达式 >]
BEGIN
<PL/SQL语句 >
END
其中的参数说明如下
(1)OR REPLACE 为可选参数,如果数据库中已经存在要创建的触发器,则先把原先的触发器删除,再重新建立触发器,或者说覆盖原先的触发器。
(2)触发时间包含 BEFORE 和 AFTER 两种,BEFORE指触发器是在触发事件发生之前执行
AFTER 指触发器在触发事件发生之后执行。
(3)触发事件,例如 INSERT,UPDATE,DELETE,CREATE,ALTER,DROP 等。
(4)<PL/SQL语句>是要执行的触发器操作。
DML触发器的创建
DML触发器在执行 DML语句时触发,可以分为INSERT、UPDATE 和 DELETE 操作,可以定义在操作之前或者之后触发,也可以指定为行级触发或者语句级触发。
语句级 DML 触发器的创建
它是默认的 DML触发器的创建,不使用 FOR EACH ROW子句。语句触发器所对应的 DML语句影响表中符合条件的所有行,但触发器只执行一次,并且不再使用 WHEN 条件语句。
创建触发器,当对emp数据表进行添加记录、更新记录和删除记录的时候,判断是否是工作时间段,如果不是工作时间段,不允许执行
如下图所示,在第2行定义了触发事件和触发时间,在程序中使用条件语句判断当前时间,如果操作不是在规定时间内,则禁止操作。
下图是在非工作时间内向数据表中添加记录的时候,产生错误警告。
在数据表 dept 上创建触发器,当在该表上插入、删除或者更新的时候,记录操作日志
分析:
这个触发器要求当向表中插入、删除或者更新数据的时候,将操作记录下来,因此需要首先建立一个数据表用于记录日志。
创建表的语句如下所示。
CREATE TABLE dept_log(action_user VARCHAR2(20)
action name VARCHAR2(20),
action time DATE)
程序代码如图所示
如上图所示,在触发器中主要使用了3个条件谓词“INSERTING”“DELETING”和“UPDATING”分别表示触发条件是否是“插入”“删除”和“更新”。
如果条件成立,则返回TRUE,否则返回FALSE。根据不同情况,向记录日志的数据表中添加操作日志。
触发器创建完成后,可以向数据表 dept 中分别插入一条数据和删除一条数据,然后查询新建立的日志表,如下图所示。
我们可以发现,新建立的日志表记录了对数据表的每一笔操作。
行级 DML 触发器的创建
行级 DML 触发器必须加入 FOR EACH ROW 子句,和语句级 DML触发器不一样,行级 DML 触发器在每次执行 DML操作的时候,如果操作一条记录,触发器就执行一次,如果涉及多条记录,那么触发器就执行多次。
在行级触发器中可以使用 WHEN 条件语句控制触发器的执行。
在行级触发器中,会使用两个标识符,即:OLD 和 :NEW,用于访问和操作当前正在处理记录中的数据。
:OLD 表示在 DML操作完成前记录的值;:NEW 表示在 DML操作完成时记录的值。
这两个标识符在不同的 DML操作下有不同的含义。
如果触发操作时,在INSERT情况下,:OLD标识符没有定义,其中所有字段内容是NULL
而:NEW 标识符指被插入的记录。
如果触发操作时,在UPDATE情况下,:OLD标识符指更新前的记录,:NEW标识符指更新后的记录如果触发操作时,在 DELETE 情况下,:OLD 标识符指被删除前的记录,而:NEW 标识符没有定义
其中所有字段内容是 NULL。在触发器内使用这两个标识符的时候,标识符后面必须跟字段名称,
例如:OLD.FIELD 或者:NEWFIELD,即不能直接使用这两个标识符引用整个记录。
此外,在条件语句 WHEN 中如果用到这两个标识符,则标识符前的“:”可以省略。
为 emp 数据表创建一个触发器,当插入新员工的时候,显示新员工的工号和姓名;当更新员工工资的时候,显示每个员工更新前后的工资;当删除员工的时候,显示被删除员工的工号和姓名
分析
:这是一个行级触发器的创建,同时在触发器内还要判断是哪种 DML 操作。
详细代码如下图所示。
如上图所示,在程序中分别使用:NEW和 :OLD 标识符实现 DML操作前后数据的获取。
此外还使用了3个条件谓词“INSERTING”“DELETING”和“UPDATING”来判断不同的 DML操作,并根据不同的操作显示不同的信息。
创建触发器完成后,可以分别插入、删除和更新数据,如下图所示。
我们可以看出,当更新数据的时候,触发器执行了多次,因为更新的部门有4条符合条件的记录因此触发器执行了4次。
行级触发器经常用于为数据表自动生成主键序列值。来看下面这个范例。
创建一个数据表用于存放学生的基本信息,并创建一个序列,然后在表上创建一个触发器,在向表中插入数据的时候,触发所建立的触发器,为学生信息表自动添加主键序列值
首先创建学生信息表
CREATE TABLE student(
stu id INT PRIMARY KEY,
stu_name VARCHAR2(20),
stu_age lNT)
在创建一个序列
CREATE SEQUENCE stu_seg;
我们可以在触发器中使用该序列的 nextval属性获取有序的数值。
下面就创建触发器以实现为学生信息表自动添加学号关键字,程序代码如下图所示。
从上图可以看到,在触发器中将获取的序列值赋予:new.stu_id。
下面就看一下向数据表中插入记录的效果,分别使用两条插入语句。
INSERT INTO student VALUES (10,'zhangsan',25);
INSERT INTO student(stu_name,stu_age) VALUES ('lisi',24);
然后查询数据表的内容,如图所示
我们可以看出,第一条插入语句虽然给出了学生编号为“10”,但是数据表中对应的 ID 却不是这个结果,
它自动在触发器中获取序列的下一个值,第二个插入语句虽然没有给出学生编号的值,仍然自动添加了序列值。