以下是我的情景:
我想在oracle中编写一个程序,有四个表,tab1,tab2,tab3,err。 tab1在两列(id number, name varchar(250))
中有一些数据,而其他列为空。
架构是
(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 :(得分:2)
这只是一个基于您在问题中输入的简单演示。最好选择 BULK 处理和 SQL%BULK_EXCEPTIONS 。 And 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个字符的procure,这样就会引发错误,我们希望将一行插入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>
我们记录了错误详情。