簡體   English   中英

Oracle DDL在自治事務中

[英]Oracle DDL in autonomous transaction

我需要在Oracle數據庫上執行一堆(最多~1000000)sql語句。 這些語句應該在結尾處產生引用一致的狀態,並且如果發生錯誤,應該回滾所有語句。 這些陳述不是以參考順序出現的。 因此,如果啟用了外鍵約束,則其中一個語句可能會導致外鍵違規,即使這種違規也將通過稍后將執行的語句修復。

我嘗試首先禁用外鍵並在執行所有語句后啟用它們。 我認為當有實際的外鍵違規時我能夠回滾。 我錯了,我發現Oracle中的每個DDL語句都以提交開始,因此無法以這種方式回滾語句。 這是我的禁用外鍵的腳本:

begin 
  for i in (select constraint_name, table_name from user_constraints
            where constraint_type ='R' and status = 'ENABLED') 
    LOOP execute immediate 'alter table '||i.table_name||' disable constraint 
                           '||i.constraint_name||''; 
  end loop;
end;

經過一些研究,我發現建議在自治事務中執行DDL語句,就像在這種情況下一樣。 所以我試圖在自治事務中運行DDL語句。 這導致以下錯誤:

ORA-00054:資源繁忙並且使用NOWAIT指定獲取

我猜這是因為主事務仍然對表有DDL鎖定。

我在這里做錯了什么,或者還有其他方法可以使這個場景有效嗎?

有幾種可能的方法。

首先要考慮的是,無論你在表級別做什么,都將適用於使用該表的所有會話。 如果您沒有對該表的獨占訪問權限,則可能不希望刪除/重新創建約束,或禁用/啟用它們。

要考慮的第二件事是你可能不希望能夠回滾一百萬次插入/更新。 回滾可以緩慢。

通常我會加載到臨時表中。 然后從臨時表中執行單個INSERT到目標表。 作為單個語句,Oracle將在最后應用所有檢查約束。

如果您無法通過臨時表(例如更新現有數據),那么在開始之前,可以將約束最終立即推遲 然后,在你的會話中,

SET CONSTRAINTS emp_job_nn, emp_salary_min DEFERRED;

然后,您可以應用更改,並在提交時驗證約束。

您應該使用DML錯誤日志記錄,因為它可以幫助識別導致違規的任何行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM