异常时将记录插入表中
Posted
技术标签:
【中文标题】异常时将记录插入表中【英文标题】:insert record into table on exception 【发布时间】:2015-02-23 08:03:19 【问题描述】:这是我的场景:
我想在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,当出现 name 大于 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;
【问题讨论】:
我刚接触数据库,所以希望有人帮我做, 创建或替换过程 exception_handler IS vSqlErr Varchar2(200) ; vSqlCode Varchar2(5) ; id2号码;名称2 varchar(250); BEGIN 全部插入 tab3 值(id,name) select * from tab1 t;其他人则插入 tab2 值(id,名称)时的例外情况; vSqlErr := substr(sqlerrm, 1, 200) ; vSqlCode := substr(sqlcode, 1, 5) ;插入错误值(vSqlErr,vSqlCode);犯罪 ;增加;结束; 我已经编辑了你的问题。而且,请在下面查看我的答案。 【参考方案1】:这只是基于您在问题中的输入的简单演示。最好使用 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.
让我们使用超过 5 个字符的 ename 值执行 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>
我们记录了错误详细信息。
【讨论】:
Kumar 因为我还想在引发异常时将记录插入到第三张表中, 所以????是什么阻止你这样做?我已经给你一个完整的答案。您需要做的就是添加另一个插入语句,如此简单。你要我给你写代码吗?你不能指望有人帮你做作业。我还为您编辑了您的问题。格式化您的代码,添加相关标签。你还有什么期待?你有一个工作测试用例的完整答案。如果对您有帮助,请将其标记为已回答。 抛出异常后如何添加另一个insert语句,将table1的所有记录插入table2,大于varchar(50)的记录全部插入table3 我是如何在代码的第 24 行添加的?问我之前你有没有试过? 我的代码也将错误插入到表中,但是我对如何在引发异常时将记录插入到第三个表中感到困惑,(意味着应该将未插入到 table2 中的记录插入到更大的尺寸表3)以上是关于异常时将记录插入表中的主要内容,如果未能解决你的问题,请参考以下文章