Oracle10g DML錯誤日誌表

atlantisholic發表於2011-04-27

當insert 語句中使用子查詢插入資料的時候(例如insert into a  select * from b),如果發生錯誤,insert語句會被中斷,且整個事務會被回滾,如果子查詢返回1000條,當在第501條時遇到錯誤。這個時候前面插入的500條資料都被回滾,既浪費時間,又浪費資源。下面將討論如何避免這種情況的發生。

 

為了使用DML記錄錯誤日誌(DML錯誤日誌表),需要在DML語句後面加一個語句,加上後DML引起的錯誤會被記錄到一張特殊的表裡(此表需要單獨建立)。此時,DML引起的異常 將不會導致所有的操作全部回滾,oracle將略過錯誤,繼續執行這個DML.

 

DML錯誤日誌表對於insert ,update,merge,delete都起作用。這裡以insert 為例。

 

Sql程式碼
  1. SQL> select * from t1;   
  2.   
  3.     DEPTNO DNAME                        LOC   
  4. ---------- ---------------------------- --------------------------   
  5.         40 develop                      China   
  6.         10 ACCOUNTING                   NEW YORK   
  7.         20 RESEARCH                     DALLAS   
  8.         30 SALES                        CHICAGO   
  9.         40 OPERATIONS                   BOSTON   
  10.   
  11. SQL> select * from t2;   
  12.   
  13.     DEPTNO DNAME                        LOC   
  14. ---------- ---------------------------- --------------------------   
  15.         40 develop                      China   
  16.         10 ACCOUNTING                   NEW YORK   
  17.         20 RESEARCH                     DALLAS   
  18.         30 SALES                        CHICAGO   
  19.   
  20. SQL> truncate table t2;   
  21.   
  22. 表被截斷。   
  23.   
  24. SQL> select * from t2;   
  25.   
  26. 未選定行   
  27.   
  28. SQL> alter table t2 add constraint pk_t2 primary key (deptno);   
  29.   
  30. 表已更改。   
  31.   
  32. SQL> insert into t2 select * from t1;   
  33. insert into t2 select * from t1   
  34. *   
  35. 第 1 行出現錯誤:   
  36. ORA-00001: 違反唯一約束條件 (TEST.PK_T2)   
  37.   
  38.   
  39. SQL> select * from t2;   
  40.   
  41. 未選定行  

 

可見插入的時候由於主鍵不能重複,導致插入出現異常,現在一條資料也沒插進去,呵呵,白費力氣。

接下來討論如何使用 LOG ERRORS 來避免這種情況:

 

1.建立DML錯誤日誌表,利用oracle自帶的包 裡面有一個儲存過程 可以拿來直接呼叫,含有2個引數,第一個:需要記錄DML錯誤日誌的表名(此例為T2),第二個:DML錯誤日誌表的名字(此例為ERR_EMPL)。 

Sql程式碼
  1. SQL> EXECUTE DBMS_ERRLOG.CREATE_ERROR_LOG('T2''ERR_EMPL');   
  2.   
  3. PL/SQL 過程已成功完成。  

     

2.插入資料

 

Sql程式碼
  1. SQL> insert into t2 select * from t1   
  2.   2  LOG ERRORS INTO err_empl ('t2_load') REJECT LIMIT 25;   
  3.   
  4. 已建立4行。   
  5.   
  6. SQL> select * from t2;   
  7.   
  8.     DEPTNO DNAME                        LOC   
  9. ---------- ---------------------------- --------------------------   
  10.         40 develop                      China   
  11.         10 ACCOUNTING                   NEW YORK   
  12.         20 RESEARCH                     DALLAS   
  13.         30 SALES                        CHICAGO  

 

可見資料插入成功了,只有主鍵重複的那一行記錄沒有插入成功。REJECT LIMIT 25的意思是如果錯誤數超過25 ,將中斷此DML,回滾操作。

 

我們再來看看 記錄錯誤日誌的那張表裡面都記錄些什麼:

Sql程式碼
  1. SQL> set linesize 500;   
  2. SQL> col DNAME format a10;   
  3. SQL> col DEPTNO format a10;   
  4. SQL> COL ORA_ERR_TAG$ format a5;   
  5. SQL> COL ORA_ERR_TAG$ format a10;   
  6. SQL> col LOC format a10;   
  7. SQL> col ORA_ERR_MESG$  format a20;   
  8. SQL> col ORA_ERR_ROWID$  format a10;   
  9. SQL> select * from err_empl   
  10. SQL> /   
  11.   
  12. ORA_ERR_NUMBER$ ORA_ERR_MESG$        ORA_ERR_RO ORA_ ORA_ERR_TA DEPTNO     DNAME      LOC   
  13. --------------- -------------------- ---------- ---- ---------- ---------- ---------- ----------   
  14.               1 ORA-00001: 違反唯一             I    t2_load    40         OPERATIONS BOSTON   
  15.                 約束條件 (TEST.PK_T2   
  16.                 )  

可以看出,此表記錄了該DML執行 期間遇到的所有的錯誤。資料之所以在遇到錯誤後仍能夠插入成功,歸功於這張表。

 

下面是關於DML錯誤日誌表column的一些描述:

 

Column Name Data Type Description

ORA_ERR_NUMBER$

NUMBER

Oracle error number

ORA_ERR_MESG$

VARCHAR2(2000)

Oracle error message text

ORA_ERR_ROWID$

ROWID

Rowid of the row in error (for update and delete)

ORA_ERR_OPTYP$

VARCHAR2(2)

Type of operation: insert (I), update (U), delete (D)

Note: Errors from the update clause and insert clause of a MERGE operation are distinguished by the U and I values.

ORA_ERR_TAG$

VARCHAR2(2000)

Value of the tag supplied by the user in the error logging clause

 

上述column的含義很容易看懂吧。

 

記得這個實用的DML錯誤日誌表,PS:此乃10G新特性,10G之前的版本不能使用。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23071790/viewspace-693910/,如需轉載,請註明出處,否則將追究法律責任。

相關文章