问题描述
我用于测试的源代码在底部。
当过程运行到第1行时, (实际上,子句'Select ztlzxh from ta_nsrlc where id=v_id'的结果为空,因此此子句将抛出异常) ,它运行到line2 ,然后再运行到line3 ,直接跳到过程的末尾。我想的是,它应该在执行line1之后转到line3 ,而不是运行line2 ,因为line1会抛出异常。另一个难题是,当代码运行到异常时,应该执行'INSERT TO TA_QT_RUNLOG'子句来记录异常消息,但在过程结束后,我还没有通过选择表TA_QT_RUNLOG得到任何结果。
你能帮我解释一下吗?
创建或替换过程CJ_TEST(V_ID,V_RETURN out VARCHAR2)为
V_DQZTLZXH查尔(3) ;
V_ERRTEXT VARCHAR2(1000) ;
开始
行1 :从TA_NSRLC中选择ZTLZXH进入V_DQZTLZXH ,其中ID=V_ID ;
线路2 : V_REURN :='1';
行3 :例外
当别人那么
--回滚;
--V_ERRTEXT :=子STR(SQLERRM, 1, 1000) ;
V_ERRTEXT := DBMS_utility.格式_错误_backtrace|||SUBSTR(SQLERRM, 1, 1000) ;
V_REURN :='0';
插入TA_QT_运行日志
选择SYS_GUID() ,
V_ID、,
'',
'',
'',
'CJ_TEST',
V_ERRTEXT ,
V_REURN ,
系统日期
来自双通道;
CJ_TEST结束;
当过程运行到第1行时, (实际上,子句'Select ztlzxh from ta_nsrlc where id=v_id'的结果为空,因此此子句将抛出异常) ,它运行到line2 ,然后再运行到line3 ,直接跳到过程的末尾。我想的是,它应该在执行line1之后转到line3 ,而不是运行line2 ,因为line1会抛出异常。另一个难题是,当代码运行到异常时,应该执行'INSERT TO TA_QT_RUNLOG'子句来记录异常消息,但在过程结束后,我还没有通过选择表TA_QT_RUNLOG得到任何结果。
你能帮我解释一下吗?
创建或替换过程CJ_TEST(V_ID,V_RETURN out VARCHAR2)为
V_DQZTLZXH查尔(3) ;
V_ERRTEXT VARCHAR2(1000) ;
开始
行1 :从TA_NSRLC中选择ZTLZXH进入V_DQZTLZXH ,其中ID=V_ID ;
线路2 : V_REURN :='1';
行3 :例外
当别人那么
--回滚;
--V_ERRTEXT :=子STR(SQLERRM, 1, 1000) ;
V_ERRTEXT := DBMS_utility.格式_错误_backtrace|||SUBSTR(SQLERRM, 1, 1000) ;
V_REURN :='0';
插入TA_QT_运行日志
选择SYS_GUID() ,
V_ID、,
'',
'',
'',
'CJ_TEST',
V_ERRTEXT ,
V_REURN ,
系统日期
来自双通道;
CJ_TEST结束;
专家解答
找不到行和找到列的值为空的行之间存在区别。例如:
顺便说一句,“当别人”那样是个坏主意。即使您捕获了一些错误信息,也要确保重新引发到该实例中的调用环境。
SQL> drop table TA_NSRLC purge;
Table dropped.
SQL> create table TA_NSRLC ( id int, ZTLZXH varchar2(10));
Table created.
SQL>
SQL> drop table TA_QT_RUNLOG purge;
Table dropped.
SQL> create table TA_QT_RUNLOG ( g varchar2(40), id int, tag varchar2(20), errm varchar2(4000), ret int, d date );
Table created.
SQL>
SQL> create or replace procedure CJ_TEST(V_ID CHAR, V_RETURN out VARCHAR2) is
2 V_DQZTLZXH CHAR(3);
3 V_ERRTEXT VARCHAR2(1000);
4 begin
5
6
7 SELECT ZTLZXH INTO V_DQZTLZXH FROM TA_NSRLC WHERE ID=V_ID;
8
9 V_RETURN := '1';
10
11 EXCEPTION
12 WHEN OTHERS THEN
13 V_ERRTEXT := DBMS_UTILITY.format_error_backtrace||SUBSTR(SQLERRM, 1, 1000);
14 V_RETURN := '0';
15 INSERT INTO TA_QT_RUNLOG
16 SELECT SYS_GUID(),
17 V_ID,
18 'CJ_TEST',
19 V_ERRTEXT,
20 V_RETURN,
21 SYSDATE
22 FROM DUAL;
23 end CJ_TEST;
24 /
Procedure created.
SQL>
SQL> insert into TA_NSRLC values (1,'X');
1 row created.
SQL> insert into TA_NSRLC values (2,null);
1 row created.
SQL>
SQL> variable r varchar2(30)
SQL>
SQL> exec CJ_TEST(1,:r);
PL/SQL procedure successfully completed.
SQL> exec CJ_TEST(2,:r);
PL/SQL procedure successfully completed.
SQL> exec CJ_TEST(3,:r);
PL/SQL procedure successfully completed.
SQL> select * from TA_QT_RUNLOG;
G ID TAG
---------------------------------------- ---------- ----------------
ERRM
--------------------------------------------------------------------
RET D
---------- ---------
2A87B0D26DCC4C2D9F52829C8FE6C4ED 3 CJ_TEST
ORA-06512: at "MCDONAC.CJ_TEST", line 7
ORA-01403: no data found
0 13-APR-16
SQL>
顺便说一句,“当别人”那样是个坏主意。即使您捕获了一些错误信息,也要确保重新引发到该实例中的调用环境。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




