触发器里面before和after的区别

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介:    关键字before和after用于标识触发时间,顾名思义,before代表触发器里面的命令在DML修改数据之前执行,after代表触发器里面的命令在DML修改数据之后执行。

   关键字beforeafter用于标识触发时间,顾名思义,before代表触发器里面的命令在DML修改数据之前执行,after代表触发器里面的命令在DML修改数据之后执行。

   读者可以结合应用场景选择使用before或者after

   下面编者分别给出beforeafter的举例。

        

         before举例:

   在emp表上面创建触发器,当输入的工资小于100时,自动将工资修改为100

         create or replace trigger tri_emp_sal_check
         before INSERT OR UPDATE ON emp
         for each row
         BEGIN
             IF
 :new.sal <100 THEN
                 :new.sal :=100;
             END IF;
         END;


   执行DML语句

         update emp set sal =90 where empno =3030;

         commit;

   发现工号3030员工的工资成功修改为100

   

   上面的触发器,我们尝试将before修改为after。编译的时候报错,不能通过。错误信息如下:

  

   编者前面已经说过,after代表触发器里面的命令在DML修改数据之后执行,既然DML操作对数据的更改已经完成,当然不允许再修改new对象的属性值了,所以此处编译不通过。

 

        after举例:

   在emp表上面创建触发器,当修改员工工资时,记录日志。为了更明显的显示效果,编者在此触发器中使用了自治事务。并且在emp表的sal列上增加了check约束,限制sal的值大于等于100

       create or replace trigger tri_emp_sal_change
     
after UPDATE ON emp
     
for each row
       DECLARE
      V_ID 
NUMBER;
      
pragma autonomous_transaction;
       BEGIN
        
IF updating('SAL')THEN
            
SELECT LOG_ID.NEXTVAL INTO V_ID FROM DUAL;
            
insert into log
             (ID,CONTENT, IP, COMPUTERNAME)
            
values
             (v_ID,
              :
new.empno ||'工资' ||'' || :old.sal ||'变更为' || :new.sal,
              sys_context('userenv','ip_address'),
              sys_context('userenv','terminal'));
             
commit;
         
END IF;
        END;

   接着编者执行如下update命令

         update emp set sal =90 where empno =3030;

   报违反检查约束条件错误,如下图所示。

  

   编者查看log表,发现log表为空。如下图所示。

 

   说明使用after的情况下,触发器里面的命令在DML修改数据之后执行,此时log中无记录,是因为DML修改数据时违反检查约束条件,触发器里面的命令没有机会执行。


   接着编者将触发器中的after替换成before

   执行相同的update命令

         update emp set sal =90 where empno =3030;

   同样违反检查约束条件,报错如下图所示。

  

         编者接着查询log表,发现成功记录了修改日志。


   说明使用before的情况下,触发器里面的命令在DML修改数据之前执行,此处虽然DML修改数据时违反检查约束条件,没有执行成功,但是由于触发器里面的命令先于DML修改数据之前执行,并且此处使用了自治事务,使得触发器里面的命令得以成功执行。

   到底应该使用before还是after,要根据具体情况而定,一般需要更改要操作的数据时使用before。如果记录日志要使用after。只有使用了after才能确保DML语句成功执行,这样记录日志才有意义。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
6月前
|
存储 SQL 关系型数据库
触发器和游标区别
触发器(Trigger)和游标(Cursor)是关系型数据库中常见的两个概念,它们在功能和使用上有一些区别。下面是触发器和游标的主要区别:
234 1
|
消息中间件 Kafka Serverless
ffc的kafka触发器和kafka的connector的主要区别
c的kafka触发器和kafka的connector的主要区别
60 1
|
存储 SQL Oracle
数据库中存储过程和触发器有什么区别?
数据库中存储过程和触发器有什么区别?
220 0
|
SQL 存储 监控
sqlserver触发器详解:sqlserver触发器after/for和instead of的区别详解(实例讲解),触发器定义创建操作打通,触发器的优缺点,触发器使用建议
sqlserver触发器详解:sqlserver触发器after/for和instead of的区别详解(实例讲解),触发器定义创建操作打通,触发器的优缺点,触发器使用建议
2189 1
|
关系型数据库 MySQL 数据库
|
5月前
|
存储 SQL 关系型数据库
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】(2)
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】
|
5月前
|
存储 SQL 关系型数据库
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】(1)
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】
|
4月前
|
存储 SQL 关系型数据库
(十四)全解MySQL之各方位事无巨细的剖析存储过程与触发器!
前面的MySQL系列章节中,一直在反复讲述MySQL一些偏理论、底层的知识,很少有涉及到实用技巧的分享,而在本章中则会阐述MySQL一个特别实用的功能,即MySQL的存储过程和触发器。
|
4月前
|
存储 SQL 数据库
MySQL设计规约问题之为什么要避免使用存储过程、触发器和函数
MySQL设计规约问题之为什么要避免使用存储过程、触发器和函数