2015-02-23 96 views
-1

這裏是我的情況:插入記錄到表上的異常

我想寫Oracle中的過程中,有四個表格,TAB1,TAB2,TAB3,ERR。 tab1有一些數據在兩列(id number, name varchar(250)),而其他是空的。

架構TAB2是

(id number, name varchar(50)), for tab3 (id number, name varchar(250))

我想插入數據從tab1到tab2,當有像例如名稱大於varchar(50)的異常時,它會插入到tab3中,並將錯誤消息插入到err表中。

因此,使用異常處理相應地將tab1中的所有記錄插入tab2和tab3中。

這是我試過但失敗了。

CREATE OR REPLACE 
PROCEDURE exception_handler 
IS 
    vSqlErr VARCHAR2(200) ; 
    vSqlCode VARCHAR2(5) ; 
    id2  NUMBER; 
    name2 VARCHAR(250); 
BEGIN 
    INSERT ALL INTO tab3 VALUES 
    (id, name 
    ) 
    SELECT * FROM tab1 t; 
EXCEPTION 
WHEN OTHERS THEN 
    INSERT INTO tab2 VALUES 
    (id, name 
    ); 
    vSqlErr := SUBSTR(sqlerrm, 1, 200) ; 
    vSqlCode := SUBSTR(SQLCODE, 1, 5) ; 
    INSERT INTO err VALUES 
    (vSqlErr, vSqlCode 
    ) ; 
    COMMIT ; 
    RAISE; 
END; 
+0

我與數據庫新鮮,所以想爲我做的人, – 2015-02-23 08:06:12

+0

在這裏,我試過,但.. – 2015-02-23 08:09:03

+0

** CREATE OR REPLACE PROCEDURE exception_handler IS vSqlErr VARCHAR2(200); vSqlCode Varchar2(5); id2號碼; name2 varchar(250); BEGIN 將所有 插入到tab3值(id,name) select * from tab1 t; EXCEPTION 何時其他則 插入tab2值(id,name); vSqlErr:= substr(sqlerrm,1,200); vSqlCode:= substr(sqlcode,1,5); 插入err值(vSqlErr,vSqlCode); 提交; RAISE; 結束; ** – 2015-02-23 08:09:43

回答

1

這只是一個簡單的演示,根據您在問題中的輸入。最好去BULK處理和SQL%BULK_EXCEPTIONSAnd don't use WHEN OTHERS blindly

假設你有一張EMP表,並且僱員姓名上的check constraint不超過5個字符。有一個EMP_ERR表,以記錄錯誤值和錯誤信息。讓我們來看看一個測試用例:

SQL> DROP TABLE emp_new PURGE; 

Table dropped. 

SQL> CREATE TABLE emp_new AS 
    2 SELECT * FROM emp WHERE 1 =2; 

Table created. 

SQL> ALTER TABLE emp_new ADD CONSTRAINT check_ename CHECK(LENGTH(ename)<=5); 

Table altered. 

SQL> DROP TABLE emp_err PURGE; 

Table dropped. 

SQL> 
SQL> CREATE TABLE emp_err 
    2 (
    3  empno NUMBER, 
    4  ename VARCHAR2(100), 
    5  err_msg VARCHAR2(250) 
    6 ); 

Table created. 

SQL> CREATE OR REPLACE 
    2 PROCEDURE p 
    3 (
    4  v_empno NUMBER, 
    5  v_ename VARCHAR2 
    6 ) 
    7 IS 
    8 vSqlErr VARCHAR2(200) ; 
    9 vSqlCode VARCHAR2(5) ; 
10 empno2 NUMBER; 
11 ename2 VARCHAR2(250); 
12 BEGIN 
13 INSERT INTO emp_new 
14  (empno, ename 
15  ) VALUES 
16  (v_empno, v_ename 
17  ); 
18 COMMIT; 
19 EXCEPTION 
20 WHEN OTHERS THEN 
21 vSqlErr := SUBSTR(sqlerrm, 1, 200) ; 
22 vSqlCode := SUBSTR(SQLCODE, 1, 5) ; 
23 INSERT 
24 INTO emp_err 
25  (
26  empno, 
27  ename, 
28  err_msg 
29  ) 
30  VALUES 
31  (
32  v_empno, 
33  v_ename, 
34  vSqlErr 
35  ||' - ' 
36  ||vSqlCode 
37  ); 
38 COMMIT ; 
39 raise; 
40 END; 
41/

Procedure created. 

允許執行同爲ename值超過5個字符從採購,從而引發錯誤,我們期待一個行插入到表emp_err

SQL> exec p(1, 'abcdef'); 
BEGIN p(1, 'abcdef'); END; 

* 
ERROR at line 1: 
ORA-02290: check constraint (SCOTT.CHECK_ENAME) violated 
ORA-06512: at "SCOTT.P", line 38 
ORA-06512: at line 1 

因此,錯誤被提出。讓我們看看它是否記錄在錯誤表中。

SQL> column ename format a10 
SQL> column err_msg format a100 
SQL> set linesize 150 

SQL> select * from emp_err; 

    EMPNO ENAME  ERR_MSG 
---------- ---------- ---------------------------------------------------------------- 
     1 abcdef  ORA-02290: check constraint (SCOTT.CHECK_ENAME) violated - -2290 

SQL> 

我們有錯誤的細節記錄。

+0

庫馬爾,因爲我也想插入記錄到第三表時,引發異常, – 2015-02-23 09:51:53

+0

所以?什麼阻止你這樣做?我給你一個完整的答案。所有你需要做的是添加另一個插入語句,非常簡單。你想讓我爲你寫代碼嗎?你不能指望有人做你的功課。我也爲你編輯了你的問題。格式化您的代碼,添加相關標籤。你還期望什麼?你有一個完整的答案與工作測試用例。如果它對您有幫助,請將其標記爲已回答。 – 2015-02-23 09:55:00

+0

如何在引發異常後添加另一個插入語句,從table1插入到table2的所有記錄以及大於varchar(50)的記錄插入到table3的所有記錄 – 2015-02-23 09:58:16