淺談例外表的應用
實驗:例外表的使用
當我們用程式向表中插入大量資料時,可能有幾條是不滿足條件的,這時候我們可能希望滿足條件的資料被執行,而程式不報錯。不滿足條件的資料呢,可能想把它放到其他地方,以備查驗。
oracle為我們提供了一種簡單方便的實現方法,通過內部的包即可將例外內容收集,並保證事務正常結束。
我們來看實驗:
環境:oracle 10g+windows2003
首先建立了一個測試表:
create table t1 as select object_name,object_type from dba_objects where 1=2;
然後我們給其新增約束:alter table t1 modify object_type not null;
這時,如果直接插入object_type為空的記錄就會報錯:
SQL> insert into T1 (OBJECT_NAME, OBJECT_TYPE)
2 values ('ICOL$', '');
insert into T1 (OBJECT_NAME, OBJECT_TYPE)
values ('ICOL$', '')
ORA-01400: 無法將 NULL 插入 ("SCOTT"."T1"."OBJECT_TYPE")
下面用dbms_errlog包來捕獲例外:
--建立例外捕獲表T1_ERROR
begin
dbms_errlog.create_error_log('T1','T1_ERROR','SCOTT');
end;
/
執行成功後我們來插入幾條資料:
begin
insert into T1 (OBJECT_NAME, OBJECT_TYPE)
values ('ICOL$', '') log errors into t1_error reject limit unlimited;
insert into T1 (OBJECT_NAME, OBJECT_TYPE)
values ('I_USER1', 'TABLE')log errors into t1_error reject limit unlimited;
commit ;
end;
/
可以看到不滿足條件的記錄被插入到了例外捕獲表中:
SQL> select * from t1_error;
ORA_ERR_NUMBER$ ORA_ERR_MESG$ ORA_ERR_ROWID$ ORA_ERR_OPTYP$ ORA_ERR_TAG$ OBJECT_NAME OBJECT_TYPE
--------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
1400 ORA-01400: 無法將 NULL 插入 ("SCOTT"."T1"."OBJECT_TYPE") I ICOL$
例外捕獲表的結構為:
SQL> desc t1_error;
Name Type Nullable Default Comments
--------------- -------------- -------- ------- --------
ORA_ERR_NUMBER$ NUMBER Y
ORA_ERR_MESG$ VARCHAR2(2000) Y
ORA_ERR_ROWID$ UROWID(4000) Y
ORA_ERR_OPTYP$ VARCHAR2(2) Y
ORA_ERR_TAG$ VARCHAR2(2000) Y
OBJECT_NAME VARCHAR2(4000) Y
OBJECT_TYPE VARCHAR2(4000) Y
以上列值還是比較好理解的,ORA_ERR_NUMBER$是oracle例外程式碼;ORA_ERR_MESG$是例外提示資訊;ORA_ERR_ROWID$是進行更新、刪除操作時產生例外的列rowid;ORA_ERR_OPTYP$的取值有I(insert)、U(update)、D(delete);
當執行update語句時,
begin
update t1 set object_type='' where object_name='CON$' log errors into t1_error reject limit unlimited;
update t1 set object_type='111' where object_name='UNDO$' log errors into t1_error reject limit unlimited;
commit ;
end;
/
SQL> select * from t1_error t;
ORA_ERR_NUMBER$ ORA_ERR_MESG$ ORA_ERR_ROWID$ ORA_ERR_OPTYP$ ORA_ERR_TAG$ OBJECT_NAME OBJECT_TYPE
--------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
1407 ORA-01407: 無法更新 ("SCOTT"."T1"."OBJECT_TYPE") 為 NULL AAAM24AAEAAAGMkAAC U CON$
ORA_ERR_ROWID$的值對應的是產生例外的待修改的列rowid。
在建立時我們並不需要去指定該表的結構,自動包含了例外程式碼、例外資訊、例外行rowid、例外型別、標誌以及所對應表的所有列。
確實很強大。但還不是全部。
試想,如果表的欄位比較多,不需要在例外捕獲表中重複寫入那麼多欄位,那麼只包含有約束的行就行啦,來看實驗:
SQL> truncate table t1;
Table truncated
SQL> create table error_show(ora_err_number$ number,ora_err_mesg$ varchar2 (200),object_type varchar2(200));
Table created
SQL>
begin
insert into T1 (OBJECT_NAME, OBJECT_TYPE)values ('ICOL$', '') log errors into error_show reject limit unlimited;
insert into T1 (OBJECT_NAME, OBJECT_TYPE)values ('I_USER1', 'TABLE')log errors into error_show reject limit unlimited;
insert into T1 (OBJECT_NAME, OBJECT_TYPE)values ('', 'TABLE') log errors into error_show reject limit unlimited;
insert into T1 (OBJECT_NAME, OBJECT_TYPE)values ('UNDO$', 'TABLE') log errors into error_show reject limit unlimited;
/*update t1 set object_type='' where object_name='CON$' log errors into t1_error reject limit unlimited;
update t1 set object_type='111' where object_name='UNDO$' log errors into t1_error reject limit unlimited;*/
commit ;
end;
ORA-38900: 缺失必需的列 "ORA_ERR_ROWID$" (例外日誌表 "ERROR_SHOW")
ORA-06512: 在 line 2
後面有嘗試缺少ORA_ERR_NUMBER$列,報錯相似。因此得出結論:當使用自定義例外表時,表中還是必須包含oracle指定的列:ORA_ERR_NUMBER$ NUMBER、ORA_ERR_MESG$、ORA_ERR_ROWID$、ORA_ERR_OPTYP$和ORA_ERR_TAG$的,我們可以修改的只是其他的列。仔細思考一下,由於例外表建立時並不知道會產生哪類錯誤;oracle需要保證所有的例外都被顯示出來,而這五列保證了錯誤顯示的完整性。
當然,我們是可以只包含以上這五列的。
SQL> drop table error_show;
Table dropped
SQL> create table error_show(ORA_ERR_NUMBER$ NUMBER,ORA_ERR_MESG$ VARCHAR2(2000),ORA_ERR_ROWID$ UROWID(4000),
ORA_ERR_OPTYP$ VARCHAR2(2),ORA_ERR_TAG$ VARCHAR2(2000));
Table created
執行匿名塊:
begin
insert into T1 (OBJECT_NAME, OBJECT_TYPE)values ('ICOL$', '') log errors into error_show reject limit unlimited;
insert into T1 (OBJECT_NAME, OBJECT_TYPE)values ('I_USER1', 'TABLE')log errors into error_show reject limit unlimited;
insert into T1 (OBJECT_NAME, OBJECT_TYPE)values ('', 'TABLE') log errors into error_show reject limit unlimited;
insert into T1 (OBJECT_NAME, OBJECT_TYPE)values ('UNDO$', 'TABLE') log errors into error_show reject limit unlimited;
/*update t1 set object_type='' where object_name='CON$' log errors into t1_error reject limit unlimited;
update t1 set object_type='111' where object_name='UNDO$' log errors into t1_error reject limit unlimited;*/
commit ;
end;
/
SQL>
PL/SQL procedure successfully completed
當只定義了oracle預設的5列作為例外表時,可以將不同表的例外都插入一個例外表中。從ora_err_mesg$列可以區分出是哪個表報錯的。
例如,將t表和t1表的例外資料都放入error_show表,查詢結果為:
SQL> select * from error_show;
ORA_ERR_NUMBER$ ORA_ERR_MESG$ ORA_ERR_ROWID$ ORA_ERR_OPTYP$ ORA_ERR_TAG$
--------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------- --------------------------------------------------------------------------------
1400 ORA-01400: 無法將 NULL 插入 ("SCOTT"."T1"."OBJECT_TYPE") I
1400 ORA-01400: 無法將 NULL 插入 ("SCOTT"."T"."OBJECT_NAME")
總的來說,例外表的功能還是蠻強大的,值得好好利用,也確實能為我們減輕很多工作負擔。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26451536/viewspace-744994/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 應用安全淺談
- 淺談混合應用的演進
- 淺談webscoket原理及其應用Web
- 單頁應用SEO淺談
- 淺談桌面應用程式的開發
- [部落格搬家]淺談Vmware的應用
- “淺談” Flutter 應用落地心得Flutter
- 【遊戲設計】淺談快速反應事件(QTE)的應用遊戲設計事件QT
- 淺談分散式 ID 的實踐與應用分散式
- 淺談移動應用的技術選型
- 淺談聚合介面的應用場景
- 淺談 iOS 應用啟動過程iOS
- 單頁應用SEO淺談(轉載)
- 再談應用程式的例項問題 (轉)
- 淺談限流元件的應用和設計原則元件
- 淺談人工智慧下智慧交通的深入應用人工智慧
- 大型直播平臺應用架構淺談應用架構
- 淺談應用動態體驗設計
- 再談多型--多型的應用舉例: (轉)多型
- FInClip開放平臺:淺談輕應用的發展
- 淺談設計模式在建安系統中的應用設計模式
- Redux複雜應用(一):淺談狀態管理Redux
- 淺談 web-桌面端應用--------nw.jsWebJS
- 淺談 K-D Tree 及其進階應用
- 淺談設計模式——單例模式設計模式單例
- 淺談canvas在web開發中的應用與優化CanvasWeb優化
- 淺談人工智慧在流媒體領域的應用人工智慧
- 淺談網路靶場的關鍵能力與應用方向
- 淺談 CBDC 系統與區塊鏈的結合應用區塊鏈
- 關於透明傳輸在通訊中的應用淺談
- 淺談常用影片加密原理及加密的幾種應用形式加密
- [原創]淺談持續整合在測試中的應用
- 淺談OA系統在應用中安全性
- 淺談資料庫防火牆技術及應用資料庫防火牆
- 淺談Java中的例項初始化器Java
- 【智慧製造】淺談ERP實施應用的流程步驟
- 淺談電子簽名留言的應用優勢及場所
- 淺談大資料在抗疫中的應用和啟示大資料