兩個關聯表間如何建立觸發器

來源:互聯網
上載者:User

實現功能描述:
       表C由表A、表B關聯產生(其中表A、表B在物理庫中,表C在記憶體資料庫中),表A、表B資料變化後通過觸發器將變化後記錄插入到小表C_inc中,通過小表觸發,最後用記憶體庫的即時同步功能將C_inc小表中的記錄同步到記憶體庫表C中。

 

問題描述:
      如何將表A、表B變化後的資料插入到小表C_inc中

 

最初實現方案:
      在物理庫建立表A、表B關聯的視圖C_view,然後在視圖C_view上建立觸發器,通過視圖上的觸發器將表的變化資料觸發到小表C_inc中。

 

遇到的問題
視圖上怎麼建立觸發器?
    

     通過查資料,在視圖上建立的觸發器為替代觸發器,其與DML觸發器不同,DML觸發器是在DML操作之外啟動並執行,而替代觸發器則代替激發它的DML語句運行,代替觸發器是行一級的。
替代觸發器的用途:
1、允許對無法變更的視圖進行修改,視圖修改後觸發基表資料修改
2、修改視圖中巢狀表格列的列
例:
create trigger ClassRoomInsert
instead of insert on class_room
declare
v_rooid rooms.room_id%TYPE;
begin
select room_id
into v_roomid
from rooms
where building = :new.building
and room_number = :new.room_number;

set room_id = v_roomid
where department = :new.department
and course = :new.course;
end;
經上所述,替代觸發器實現的是允許無法變更的視圖進行修改,而不是我想要的基表變化了,視圖隨之更新,根據視圖的更新插入小表C_inc中記錄。

 

第二種實現方案:
在觸發器中進行2個表資料的關聯,觸發器如下:
CREATE OR REPLACE TRIGGER t_mmdb_on_balance_type
after insert or update on balance_type_attr
for each row
declare
begin
    if inserting then
            insert into mmdb_balance_type_inc(op_sn,op_type,op_time,BALANCE_TYPE_ID,BALANCE_TYPE_ATTR,ACCT_ITEMS,PRIORITY,CYCLE_UPPER_TYPE,CYCLE_UPPER,CYCLE_LOWER_TYPE,CYCLE_LOWER,PAYMENT_LIMIT_TYPE,PAYMENT_LIMIT)
            select 0,'1',sysdate,a.BALANCE_TYPE,a.BALANCE_TYPE_ATTR,a.ACCT_ITEMS,b.PRIORITY,a.CYCLE_UPPER_TYPE,
            a.CYCLE_UPPER,a.CYCLE_LOWER_TYPE,a.CYCLE_LOWER,a.PAYMENT_LIMIT_TYPE,a.PAYMENT_LIMIT
            from BALANCE_TYPE_ATTR a,bss_acctbook_info b
            where a.BALANCE_TYPE = b.acctbooktype
            and a.BALANCE_TYPE = :new.BALANCE_TYPE;
    elsif updating then
            insert into mmdb_balance_type_inc(op_sn,op_type,op_time,BALANCE_TYPE_ID,BALANCE_TYPE_ATTR,ACCT_ITEMS,PRIORITY,CYCLE_UPPER_TYPE,CYCLE_UPPER,CYCLE_LOWER_TYPE,CYCLE_LOWER,PAYMENT_LIMIT_TYPE,PAYMENT_LIMIT)
            select 0,'2',sysdate,a.BALANCE_TYPE,a.BALANCE_TYPE_ATTR,a.ACCT_ITEMS,b.PRIORITY,a.CYCLE_UPPER_TYPE,
            a.CYCLE_UPPER,a.CYCLE_LOWER_TYPE,a.CYCLE_LOWER,a.PAYMENT_LIMIT_TYPE,a.PAYMENT_LIMIT
            from BALANCE_TYPE_ATTR a,bss_acctbook_info b
            where a.BALANCE_TYPE = b.acctbooktype
            and a.BALANCE_TYPE = :new.BALANCE_TYPE;
    end if;
end;

 

更新資料時報如下錯誤:
   ORA-04091: table OCSBILLTEST.BALANCE_TYPE_ATTR is mutating, trigger/function may not see it
   ORA-06512: at "OCSBILLTEST.T_MMDB_ON_BALANCE_TYPE", line 11
   ORA-04088: error during execution of trigger 'OCSBILLTEST.T_MMDB_ON_BALANCE_TYPE'
基本意思是在是因為在TRIGGER中訪問了變化表所引起的,ORACLE資料上說如INSERT語句僅影響一個行,觸發器不把觸發表當作變化表處理,也就是在trigger裡面不要再訪問trigger所在的表了。

修改後的實現方案:
在基表表A、表B上建立觸發器,觸發器上使用遊標操作,進行2個表的關聯操作,觸發器如下:
CREATE OR REPLACE TRIGGER t_mmdb_on_balance_type
after insert or update on balance_type_attr
for each row
declare
    cursor c_priority is
      SELECT priority FROM BSS_ACCTBOOK_INFO where ACCTBOOKTYPE = :new.BALANCE_TYPE;
begin
 if inserting then
  for v_record in c_priority loop
         insert into mmdb_balance_type_inc(op_sn,op_type,op_time,BALANCE_TYPE_ID,BALANCE_TYPE_ATTR,ACCT_ITEMS,PRIORITY,CYCLE_UPPER_TYPE,CYCLE_UPPER,CYCLE_LOWER_TYPE,CYCLE_LOWER,PAYMENT_LIMIT_TYPE,PAYMENT_LIMIT)
         values(0,'1',sysdate,:new.BALANCE_TYPE,:new.BALANCE_TYPE_ATTR,:new.ACCT_ITEMS,v_record.priority,:new.CYCLE_UPPER_TYPE,
         :new.CYCLE_UPPER,:new.CYCLE_LOWER_TYPE,:new.CYCLE_LOWER,:new.PAYMENT_LIMIT_TYPE,:new.PAYMENT_LIMIT);
     end loop;
 elsif updating then
     for v_record in c_priority loop
         insert into mmdb_balance_type_inc(op_sn,op_type,op_time,BALANCE_TYPE_ID,BALANCE_TYPE_ATTR,ACCT_ITEMS,PRIORITY,CYCLE_UPPER_TYPE,CYCLE_UPPER,CYCLE_LOWER_TYPE,CYCLE_LOWER,PAYMENT_LIMIT_TYPE,PAYMENT_LIMIT)
         values(0,'2',sysdate,:new.BALANCE_TYPE,:new.BALANCE_TYPE_ATTR,:new.ACCT_ITEMS,v_record.priority,:new.CYCLE_UPPER_TYPE,
         :new.CYCLE_UPPER,:new.CYCLE_LOWER_TYPE,:new.CYCLE_LOWER,:new.PAYMENT_LIMIT_TYPE,:new.PAYMENT_LIMIT);
     end loop;
 end if;
end;

由於自己在SQL方面知識比較欠缺,造成建一個關聯表的觸發器用了4個多小時,還好最後成功的解決了問題,將這之間遇到的問題及解決辦法整理了一下,希望能對有同樣困擾的人有所協助。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.