• 在oracle中使用Trigger


    1、初始目标

    在对表h1插入一条数据时,同时插入一条重复的数据(只有主键不同)

    2、在PL/SQL里New一个Trigger或者手动敲入代码

    先说明一下,表h1包括4列ID、C1、C2、C3

    create or replace trigger Trigger_Test
      after insert on h1
      for each row
    declare
      --variables
    begin
      insert into h1 values(:new.C1, :new.C2, :new.C3, :new.ID);
    end Trigger_Test;
    

    3、F8编译通过,新建一个窗口执行insert窗口,测试trigger是否有效,用了一个名为sequence_test的序列:

    insert into h1 values('aa','bb','cc',sequence_test.nextval);
    

    报错:表h1发生了变化,触发器/函数不能读。

    4、网上搜的说法是“触发器不能修改触发表的数据,除非使用自治事务”,OK那就用自治事务:

    declare
      --variables
    //改为:
    declare
      pragma autonomous_transaction;
    

    再试报错:等待资源时检测到死锁。仔细一查,哦原来是目标有问题,Insert连着Insert,无限循环,不是资源死锁就是内存不足或者栈溢出。

    5、目标更新为:在对表h1插入一条数据时,同时插入一条相同的数据到历史表里,把trigger里的insert修改为:

    insert into h1_history values(:new.C1, :new.C2, :new.C3, :new.ID);
    

    再跑又报错:检测到活动的自治事务处理,已经回退。

    6、网上接着搜,说是有事务没提交。其实这是之前目标设定有问题,触发器一般不会修改触发表,用了自治事务,就要commit;如果是插入历史表,可以都不加。

    declare
      pragma autonomous_transaction;
      commit;
      delete from h1 where ID = 1;
      commit;
    
    //如果不操作触发表,则可以去掉自治事务的这一串声明
    declare
      insert into h1_history values(:new.C1, :new.C2, :new.C3, :new.ID);
    

    7、小结

    1. Trigger在修改其他表(非触发表)的时候,最方便,直接像写存储过程即可;
    2. 若要使用Trigger修改触发表的数据,需要配合使用自治事务并commit,比较麻烦;
    3. 对新操作的记录本身(比如新Insert/Update/Delete的数据),无法做修改,并且如果强行修改的话,既不会报错,也没有效果。
  • 相关阅读:
    springboot中jpa+lombok
    slf4j管理日志,info和error分开存储,每天一个日志文件
    redis内存策略
    redis持久化策略
    Json与对象之间的转化
    Json--01
    缓存中应注意的问题
    面试中的数据库如何优化?
    公司中服务器部署步骤
    Nginx故障迁移
  • 原文地址:https://www.cnblogs.com/AlexanderYao/p/4514377.html
Copyright © 2020-2023  润新知