2011-03-30 61 views
2

我在10g數據庫中繼承了一些令人討厭的PL/SQL代碼,這些代碼從一個特定的表中刪除不正確的行。查找行刪除的PL/SQL來源

我知道刪除發生,因爲我設置了一個觸發器,用於在行被刪除時記錄行的詳細信息。

顯然,簡單的答案是「搜索」從「刪除」。「但是,其中涉及的程序中只有一個包含18頁的PL/SQL,並且該程序有大約25個參數。刪除通過一些非常複雜的連接,其涉及許多參數,它是討厭的,討厭的代碼,這將需要一些時間來調試。

是否有甲骨文工具,可以幫助我找出語句導致刪除?

會是什麼完美的是一個觸發器,記錄刪除堆棧跟蹤,但我不認爲存在。

我被告知打開跟蹤可能會有所幫助,但也可能是一個很大的練習,具體取決於有多少跟蹤輸出。

我也想過也許鎖定表,看到其中一個錯誤被拋出,但鑑於該代碼無疑做大量插入刪除之前,我不知道錯誤是任何幫助。

所有的想法都表示讚賞。

回答

1

添加包裝規格到應用程序,保持一個簡單的狀態變量,例如

create or replace package app_state is 
    g_state varchar2(30); 
end; 

在每次刪除PL/SQL代碼之前,將此狀態設置爲允許您識別刪除語句的內容,例如,

app_state.g_state := 'delete 1'; 
delete ... very ... complex ... stuff ... 
app_state.g_state := 'delete 2'; 
delete ... more ... complex ... stuff ... 

可以讀取並保存在你已經觸發app_state.g_state的價值。

這使您可以監視/記錄哪個刪除語句刪除了哪一行。

+0

接受簡單而有效。 – wadesworld 2011-04-01 12:51:08

2

這聽起來像你正在使用一個大的ETL過程?我可能會開始去了解這個人:

  • 複製源數據的(非常)小的子集到QA或開發環境,包括我知道會被刪除幾行,和一些我知道不會(可能來自前一天的備份數據)。

  • 在每個SQL「delete」語句中使用帶有斷點的PL/SQL調試器運行代碼。檢查每個「刪除」發生後,您的行是否仍然存在。對於像TOAD這樣的IDE來說,這樣做更容易,但只能使用oracle技術來完成。見http://www.adp-gmbh.ch/ora/plsql/debug.html

  • 正如您所提到的,還有PL/SQL跟蹤,它可以用於在較小的代碼段中識別類似的問題。這些文件非常大,速度非常快,因此像以前那樣使用小數據子集進行跟蹤可能是明智的做法。

  • 對於異常堆棧跟蹤,看看這裏還有 - http://paranoid-engineering.blogspot.com/2008/07/oracle-exception-handling-stack-trace.html 您可以添加一些額外的代碼來處理異常,然後「鎖定」表生成「刪除」例外

在每個「DELETE」sql語句之後,您可能不得不訴諸舊的備用數據庫 - DBMS_OUTPUT。

1

函數DBMS_UTILITY.FORMAT_CALL_STACK創建當前執行的堆棧跟蹤。你可以從你的觸發器中調用它並將結果寫入一個單獨的表(在一個自治事務中)。

+0

觸發器調用堆棧是否與SP的調用堆棧有關。假設觸發器是一個具有自己堆棧的匿名塊,並不直接從SP調用。 – 9000 2011-03-30 16:18:39

+0

是的,你是對的。這是一個單獨的堆棧。所以我的方法是行不通的。 – Codo 2011-03-30 18:57:57

2

您可能想要考慮在該表上設置審覈,至少在您試圖弄清楚發生了什麼時。 10g具有細粒度的審計和DML審計。這裏有一個有用的link

下面是更多complete example,顯示詳細的輸出。

希望它可以幫助