zoukankan      html  css  js  c++  java
  • 在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的数据),无法做修改,并且如果强行修改的话,既不会报错,也没有效果。
  • 相关阅读:
    如何在Windows下安装sass和compass
    HTTP 请求头中的 X-Forwarded-For
    HTTP 代理原理及实现
    node.js使用经验记录
    完美方案——iOS的WebView自适应内容高度
    购物车商品加减效果
    C++17新特性
    栈实现迷宫求解(c++版)
    二叉树遍历及实现
    经典乱码“烫烫烫”和“屯屯屯”
  • 原文地址:https://www.cnblogs.com/AlexanderYao/p/4514377.html
Copyright © 2011-2022 走看看