2012-09-25 83 views
0

我有一打我想保留更改歷史記錄的表格。對於每一個我創建了第二個表結束_HISTO和添加領域modtime,行動,用戶。可以從Oracle中的觸發器調用動態SQL嗎?

在我插入,修改或刪除表中的記錄之前,我調用了一個oracle過程(從我的delphi應用程序)將實際值複製到組織表中,然後執行操作。

我的方法,由表名

我被告知,我無法調用此生成經由DBA_TAB_COLUMNS動態SQL,然後執行所生成的(插入tablename_histo(字段多個)選擇字段,SYSDATE,「acition」,用戶標識因爲它必須選擇觸發器被觸發的表,這是真的嗎?是否有可能實現我需要的功能?

+0

它爲什麼需要動態?您是否可以在修改其引用的基表和歷史表的同時更新每個觸發器以反映任何新列? –

+0

此外,你看着甲骨文細粒度審計和/或DBMS工作區包?你的數據庫版本是什麼? –

回答

2

假設您想要使用觸發器(而不是其他任何方法在Oracle-- Workspace Manager,Total Recall,Streams,Fine_Grained Auditing等)中跟蹤歷史數據),你可以在觸發器中使用動態SQL,但動態SQL是subj等到靜態SQL受制於的相同規則。甚至行級觸發器中的靜態SQL也不能通常查詢定義觸發器的表而不產生突變表異常。

但是,您可以使用相同的數據字典表在第一個位置編寫一些動態SQL來生成觸發器,而不是從觸發器中調用動態SQL。觸發器本身會靜態引用:new.column_name:old.column_name。當然,您必須編輯觸發器,或者在添加新列時重新運行動態創建觸發器的過程。既然你可能需要將列添加到主表和歷史表中,但是,這通常不是太大。

0

Oracle不允許觸發器對定義觸發器的表執行SELECT操作。如果你嘗試,你會得到可怕的「變異表」的錯誤(ORA-04091),雖然有方法可以解決錯誤,他們添加了大量的複雜的價值不大。如果你真的想每次你的表更新時間來建立一個動態查詢(IMO這是從性能的角度來看是一個壞主意 - 我發現,元數據查詢通常是緩慢的,但情況因人而異),它應該結束了看起來像

strAction := CASE 
       WHEN INSERTING THEN 'INSERT' 
       WHEN UPDATING THEN 'UPDATE' 
       WHEN DELETING THEN 'DELETE' 
      END; 

INSERT INTO TABLENAME_HISTO 
    (ACTIVITY_DATE, ACTION, MTC_USER, 
    old_field1, new_field1, old_field2, new_field2) 
VALUES 
    (SYSDATE, strAction, USERID, 
    :OLD.field1, :NEW.field1, :OLD.field2, :NEW.field2) 

分享和享受。