`

oracle 触发器实现多表级联修改

阅读更多
应用场景:
table name A
field name:
             yesterday date(昨日日期)
             today date(今日日期)
             yesterdaynum number(昨日数量=totle)
             todaynum number(今日数量)
             totle number(今日总量=yesterdaynum+todaynum)

可见表A昨日数据需要与今日数据相关联,若用户修改了三天前的一个totle字段值,理论上来说应该在这三天发生的数据都要做相应修改。

实现方案:
在table A上做 TRIGGER,每当有update操作时,执行存储过程修改后面相关数据。
CREATE OR REPLACE TRIGGER tr_hyzcupdate
  after UPDATE ON A  
  FOR  EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  SNWZ.TAL_TEST.p_testEmptyCursor(:old.today,:new.totle);
end tr_hyzcupdate;


create or replace package TAL_TEST is

 TYPE myCursorType IS REF CURSOR;

 PROCEDURE p_testEmptyCursor(updatedate in date,totle in number);
  
end TAL_TEST;


  
   create or replace package body TAL_TEST is
 PROCEDURE p_testEmptyCursor(updatedate in date,totle in number)
   is
   pragma autonomous_transaction;
 maxdate date;
 testdate date;
 rowRecord A%ROWTYPE;
 myCursorFirst myCursorType ;
 execSql varchar2(2000);
 updateRowRecord A%ROWTYPE;
 updateMyCursorFirst myCursorType ;
 --disableTrigger varchar2(2000);
 --enableTrigger varchar2(2000);
 begin
   --查询出表中最后一条记录
   select max(today) into maxdate from A;
   testdate:=updatedate;
   --disableTrigger:='alter trigger  tr_hyzcupdate disable';
   --enableTrigger:='alter trigger  tr_hyzcupdate enable';
   -- execute immediate disableTrigger;
   --循环需要修改的记录
   while testdate !=maxdate+1 loop
      
      OPEN myCursorFirst FOR
      select *  from A t where t.today=testdate;
      FETCH myCursorFirst INTO rowRecord; 
      IF myCursorFirst%notfound THEN
       exit;
       ELSE
        
         OPEN updateMyCursorFirst FOR
         select *  from A t where t.today=(testdate+1);
         dbms_output.put_line( testdate+1);
          FETCH updateMyCursorFirst INTO updateRowRecord; 
            IF updateMyCursorFirst%found THEN
             -- else
             if testdate=updatedate then
                 dbms_output.put_line('the first update');
                  execSql:= 'update A t set t.yesterdaynum='||totle||',t.totle='||(totle+updateRowRecord.todaynum) ||' where to_char(t.today,''YYYY-mm-dd'')='''||to_char(updateRowRecord.Today,'YYYY-MM-dd''')||'';
                 else
                    execSql:= 'update A t set t.yesterdaynum='||rowRecord.totle||',t.totle='||(rowRecord.totle+updateRowRecord.todaynum) ||' where to_char(t.today,''YYYY-mm-dd'')='''||to_char(updateRowRecord.Today,'YYYY-MM-dd''')||'';
               end if;
             
              dbms_output.put_line(execSql);
              execute immediate execSql;
              commit;
           
        END IF;
         end if;
         testdate:=testdate+1;
     end loop;
   --  execute immediate enableTrigger;
     end;
end TAL_TEST;



在此遇到几个问题有的解决有的没解决:
问题一:关于变异表问题,因为涉及到修改时候触发动作,而后又操作本表,所以会出现deadlock问题,解决方法--通过设置oracle自治事务

问题二:例如today是2015-03-13 其实上面的代码做了两次update a where today=2015-03-13,为什么这样做呢?因为触发update时候,在执行存储过程期间,被触发的那条记录是没有提交的,所以我们修改后面的记录虽然有commit ,但是数据是不会发生变化的,解决方法,在存储过程中单独执行update a where today=2015-03-13;

问题三:因为触发器是update,而存储过程也是循环每条数据执行update,所以每次update都会调用触发器,所以如果修改n条记录,其实会触发n次触发器,就是这个问题不知如何解决,试过的方案有:在执行存储过程期间将trigger set disable,不成功。

分享到:
评论

相关推荐

    Oracle触发器与存储过程高级编程-第3版itpub.rar

    《Oracle触发器与存储过程高级编程》第3版是一本深入探讨Oracle数据库中触发器和存储过程技术的专业书籍。在Oracle数据库系统中,触发器和存储过程是数据库管理员和开发人员进行复杂业务逻辑处理和数据管理的重要...

    使用Java编写Oracle触发器的实现.pdf

    2. **级联更改**:虽然级联引用完整性约束是更有效的方法,但触发器可以用于跨相关表执行更复杂的级联更新操作。 3. **复杂限制**:相比于CHECK约束,触发器能执行更复杂的逻辑,因为它可以访问其他表中的数据。这...

    Oracle触发器语法

    - **级联更新**:当某一表中的数据更改时,可以触发对其他相关表的更新,保持数据的一致性。 - **拒绝不合规操作**:可以防止破坏数据完整性的事务,例如,阻止插入与主键不匹配的外部键。 **使用触发器管理数据...

    oracle触发器.doc

    Oracle触发器是数据库对象,它在特定的数据库事件发生时自动执行,比如当数据插入、更新或删除时。触发器可以用于实现复杂的数据管理和业务逻辑,确保数据的一致性和完整性。以下是对Oracle触发器的详细解释: 1. *...

    oracle触发器(trigger).pdf

    - 触发器可以实现跨表的级联更改,但级联引用完整性约束通常更为高效。 - 触发器能够强制执行比CHECK约束更复杂的约束,且可以引用其他表的列。 - 同一表中可以有多个同类触发器,以应对不同的数据修改响应。 1.4 ...

    解析Oracle中多表级联删除的方法

    以下将详细介绍三种在Oracle中实现多表级联删除的方法。 **方法一:创建约束时设定级联删除** 在创建表时,可以通过定义外键约束并指定`ON DELETE CASCADE`选项来实现级联删除。例如: ```sql CREATE TABLE "U_...

    Oracle触发器与存储过程高级编程

    文件"Oracle触发器与存储过程高级编程.pdf"很可能是这本书或教程的电子版,它会详细讲解触发器和存储过程的各种高级特性,包括但不限于:触发器的时间线(Before/After)、级联触发、触发器中的事务控制、存储过程的...

    oracle触发器(trigger)[定义].pdf

    Oracle触发器是数据库管理系统Oracle中的一种特殊存储过程,它的运行不是由程序调用或手动启动,而是由特定的数据库事件触发,例如对表的INSERT、DELETE或UPDATE操作。触发器常用于增强数据的完整性约束和实施复杂的...

    Oracle触发器好东东

    通过上述示例可以看出,Oracle触发器是一种非常强大且灵活的机制,可以帮助维护数据的一致性和完整性,同时也可以用于实现复杂的业务逻辑。正确地设计和使用触发器对于构建高质量的数据库应用程序至关重要。

    Oracle数据库中的级联查询、级联删除、级联更新操作教程

    Oracle数据库中的级联查询、级联删除和级联更新是数据库设计中常用的操作,它们用于在多表关联的关系型数据库中实现数据的联动处理。在Oracle中,这些操作主要涉及外键约束和触发器。 首先,级联查询是通过自连接来...

    oracle 触发器可以参考书写对于学习有帮助

    学习Oracle触发器,需要理解PL/SQL编程基础,掌握如何创建、修改和删除触发器,以及如何在实际项目中适当地应用它们。此外,还要注意避免触发器的滥用,以免引入不必要的复杂性和性能问题。 在学习过程中,可以参考...

    oracle触发器与存储过程高级编程

    **一、Oracle触发器** 触发器是一种数据库对象,它在特定的数据库事件(如INSERT、UPDATE或DELETE)发生时自动执行。触发器可以用于执行复杂的业务规则,如级联更新、历史记录跟踪、并发控制等。以下是一些关键知识...

    Oracle触发器

    ### Oracle触发器详解 在Oracle数据库管理中,触发器是一种重要的机制,用于自动执行响应于特定数据库事件(如数据插入、更新或删除)的SQL语句。触发器可以帮助确保数据完整性,实现复杂业务规则,以及自动化...

    数据库 触发器 应用

    - **级联更改**:描述中提到,触发器能够实现在相关表之间的级联更改。例如,当一个表的数据发生变化时,可以自动更新另一个相关的表,以保持数据同步。 - **审计跟踪**:触发器可用于记录数据变化的历史,便于...

    精通Oracle核心技术和项目实战之触发器.

    ### 精通Oracle核心技术和项目实战之...通过以上内容的学习,我们可以深入了解Oracle触发器的强大功能及其在实际项目中的应用价值。触发器不仅可以提高数据的安全性和完整性,还能简化开发流程,提升系统的整体性能。

    MySQL与Oracle 差异比较之六触发器

    此外,Oracle可能有更复杂的触发器级联和嵌套规则。 在实际应用中,开发者需要根据项目需求和数据库系统的特性选择合适的触发器实现方式。理解这些差异可以帮助开发者更有效地管理和维护数据库,提高系统性能,并...

    触发器介绍

    - **执行上下文**:SQL 触发器支持更多的自定义选项,而 Oracle 触发器更注重于简化执行过程。 - **新旧行标识**:SQL 使用 `inserted()` 和 `deleted()` 来标记新旧行,Oracle 则使用 `new` 和 `old`。 #### ...

    oracle_11gR212

    触发器可以创建在单个表上,也可以跨多个表,实现级联操作。 **创建触发器**的过程涉及定义触发器名称,指定触发事件,以及编写在触发时执行的PL/SQL代码块。例如,一个简单的触发器可能会在插入新记录时检查某个...

Global site tag (gtag.js) - Google Analytics