Oracle10g新特性——記錄DML錯誤日誌(二)
當一個DML執行的時候,如果遇到了錯誤,則這條語句會整個回滾,就好像沒有執行過。不過對於一個大的DML而言,如果個別資料錯誤而導致整個語句的回滾,會浪費很多的資源和執行時間,從10g開始Oracle支援記錄DML語句的錯誤,而允許語句自動繼續執行。
這篇介紹DML記錄語句的限制。
Oracle10g新特性——記錄DML錯誤日誌(一):http://yangtingkun.itpub.net/post/468/479317
上一篇簡單介紹了DML記錄語句的限制,雖然所有的例子都是利用INSERT語句,但是LOG ERRORS語句並沒有這個限制,UPDATE、DELETE和MERGE都可以使用這個語句。下面要說的才是LOG ERRORS語句的限制。
當發生下面的情況時,錯誤記錄語句無效,Oracle會自動回滾錯誤的語句:
違反延遲約束;
直接路徑的INSERT或MERGE語句違反了唯一約束或唯一索引;
更新操作違反了唯一約束或唯一索引。
下面先看看違反延遲約束的情況:
SQL> DROP TABLE T PURGE;
表已刪除。
SQL> DROP TABLE T_ERROR_LOG PURGE;
表已刪除。
SQL> CREATE TABLE T
2 (ID NUMBER,
3 NAME VARCHAR2(10),
4 AGE NUMBER(3),
5 CONSTRAINT CK_T_AGE CHECK (AGE < 150)
6 DEFERRABLE
7 INITIALLY DEFERRED);
表已建立。
SQL> EXEC DBMS_ERRLOG.CREATE_ERROR_LOG('T', 'T_ERROR_LOG')
PL/SQL 過程已成功完成。
SQL> DESC T_ERROR_LOG
名稱 是否為空? 型別
----------------------------------------------------------------- -------- ---------------
ORA_ERR_NUMBER$ NUMBER
ORA_ERR_MESG$ VARCHAR2(2000)
ORA_ERR_ROWID$ ROWID
ORA_ERR_OPTYP$ VARCHAR2(2)
ORA_ERR_TAG$ VARCHAR2(2000)
ID VARCHAR2(4000)
NAME VARCHAR2(4000)
AGE VARCHAR2(4000)
下面測試一下LOG ERRORS語句:
SQL> INSERT INTO T VALUES (1, '1234567890A', 5)
2 LOG ERRORS INTO T_ERROR_LOG REJECT LIMIT 1;
已建立0行。
SQL> SELECT COUNT(*) FROM T_ERROR_LOG;
COUNT(*)
----------
1
下面嘗試違反延遲約束:
SQL> INSERT INTO T VALUES (1, 'ABC', 200)
2 LOG ERRORS INTO T_ERROR_LOG REJECT LIMIT 1;
已建立 1 行。
SQL> COMMIT;
COMMIT
*
第 1 行出現錯誤:
ORA-02091: 事務處理已回退
ORA-02290: 違反檢查約束條件 (YANGTK.CK_T_AGE)
SQL> SELECT COUNT(*) FROM T_ERROR_LOG;
COUNT(*)
----------
1
由於延遲約束的檢查在COMMIT時刻進行,而不是在DML發生的時刻,因此不會利用LOG ERRORS語句將違反結果的記錄插入到記錄表中,這也是很容易理解的。
下面看看直接路徑插入違反唯一約束的情況:
SQL> ALTER TABLE T DROP CONSTRAINT CK_T_AGE;
表已更改。
SQL> ALTER TABLE T ADD PRIMARY KEY(ID);
表已更改。
SQL> INSERT /*+ APPEND */ INTO T
2 SELECT MOD(ROWNUM, 10), SUBSTR(TNAME, 1, 10), 10
3 FROM TAB
4 LOG ERRORS INTO T_ERROR_LOG
5 REJECT LIMIT UNLIMITED;
INSERT /*+ APPEND */ INTO T
*
第 1 行出現錯誤:
ORA-00001: 違反唯一約束條件 (YANGTK.SYS_C0011606)
SQL> SELECT COUNT(*) FROM T_ERROR_LOG;
COUNT(*)
----------
1
直接路徑插入本身就很特殊,在執行過程中會繞過很多常規SQL執行的步驟,因此LOG ERRORS語句對其無效也是可以理解的。
最後來看看更新語句違反唯一約束的情況:
SQL> SELECT * FROM T;
未選定行
SQL> INSERT INTO T
2 SELECT MOD(ROWNUM, 10), SUBSTR(TNAME, 1, 10), 10
3 FROM TAB
4 LOG ERRORS INTO T_ERROR_LOG
5 REJECT LIMIT UNLIMITED;
已建立10行。
SQL> UPDATE T
2 SET ID = 1
3 WHERE ID = 2
4 LOG ERRORS INTO T_ERROR_LOG
5 REJECT LIMIT UNLIMITED;
UPDATE T
*
第 1 行出現錯誤:
ORA-00001: 違反唯一約束條件 (YANGTK.SYS_C0011606)
可以看到,如果更新操作導致了唯一約束或唯一索引衝突,也是不會記錄到錯誤記錄表中的。至於為什麼更新操作會產生這種情況,還沒有想明白,不過主鍵的衝突和其他約束衝突有所區別,Oracle在處理的時候很可能會有所考慮。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-558326/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle10g新特性——LOG ERRORS記錄DML錯誤日誌(二)OracleError
- Oracle10g新特性——記錄DML錯誤日誌(三)Oracle
- Oracle10g新特性——記錄DML錯誤日誌(一)Oracle
- Oracle10g新特性——LOG ERRORS記錄DML錯誤日誌(三)OracleError
- Oracle10g新特性——LOG ERRORS 記錄DML錯誤日誌(一)OracleError
- 10g release 2的新特性--記錄DML錯誤日誌
- Oracle10g DML錯誤日誌表Oracle
- oracle 12c 新特性之二:可以記錄DDL日誌Oracle
- Oracle12c新特性(2)記錄DDL日誌Oracle
- 新特性解讀 | MySQL 8.0錯誤日誌深入過濾(上)MySql
- [翻譯] 除錯 Rxjs(二):日誌記錄除錯JS
- mysql 日誌之錯誤日誌MySql
- php日誌,記錄日誌PHP
- 排查錯誤日誌
- mysql之 日誌體系(錯誤日誌、查詢日誌、二進位制日誌、事務日誌、中繼日誌)MySql中繼
- Apche日誌系列(2):錯誤日誌(轉)
- Mabatis配置錯誤日誌BAT
- net 日誌分析錯誤
- 日誌查詢錯誤
- 錯誤日誌檢視
- SQL Server 錯誤日誌SQLServer
- oracle 10g_dbms_errlog --記錄插入表中錯誤dmlOracle 10g
- laravel5.7 不記錄 sql 報錯日誌,自定義日誌資訊LaravelSQL
- 日誌記錄器
- dml操作重做日誌分析
- MySQL 狂寫錯誤日誌MySql
- jdon框架日誌資訊錯誤框架
- Laravel sql 日誌記錄LaravelSQL
- secureCRT記錄操作日誌Securecrt
- 記錄日誌檔案
- PHP日誌記錄方法PHP
- oracle日誌操作記錄Oracle
- Kafka錯誤記錄Kafka
- Oracle12C新特性_DDL日誌Oracle
- 方便檢視11g錯誤日誌的指令碼(新)指令碼
- SAP 錯誤日誌的調查
- node錯誤處理與日誌
- 上一個日誌的錯誤