TCBS后台的批量存储过程中,N次看到如下的代码处理逻辑,
上述代码包含了保存点.if代码块,异常,异常后的处理代码
那么我的测试要点:
| 1,发生异常时,会执行到保存点吗 2,保存点执行后(即:rollback to 执行后),还会继续执行后续的代码,还是直接退出存储过程 3,exception异常代码块,一直对于when others then的理解, others是可以捕获所有的oracle异常吗,这样我就可以编写相关的处理代码,不至于让代码中断了.代码的健壮性就增强了 |
SQL> declare
2 v_a varchar2(10);
3 begin
4 insert into log_test values(1,'zxy');
5 savepoint sp1;
6 v_a:='mv';
7 insert into other_log values(2,'zxz');
8 if v_a='mv' then
//保存点sp1的作用,在后面执行rollback to sp1,就会保存sp1之前代码所作的工作,而不会完全rollback,尤其对于金融系统,利用游标处理若干账号的业务情形
9 rollback to sp1;
//dbms_output仅用于调试显示用
10 dbms_output.put_line('开始执行rollback to之后的代码');
11
//在TCBS后台的大量存储过程中采用了多个begin exception end的代码块
//以前不太懂,这样就会增强模块化,每块代码具有独立的处理能力,再者
//处理逻辑显得清晰
//从业务流程上看也很清楚,一环扣一环,直至流程结束
12 begin
//注:log_test表的第二列是varchar2(10)的大小,故意insert超过列大小的数据
//以测试when others then是否可以捕获到此异常
13 insert into log_test values(88,'after rollback to');
14 exception //异常块关键字 exception,而非exceptions
//采取when others then的作用就是在上述insert子句出错,整个plsql或者
存储过程可以继续执行,不会导致中断
15 when others then //在此我们只写一种异常处理分支,当然实际情况可以有多个类似的分支
//在此我只是用关键字sqlerrm及sqlcode显示insert语句具体异常的相关信息
//sqslerrm表示oracle出错的原因(含:文字及错误号),sqlcode仅是oracle错误号
16 dbms_output.put_line(sqlerrm||sqlcode);
//编写如下insert into 语句,为了测试在捕获后insert into之类的dml语句可以继续
//执行吗,答案是可以执行
17 --捕获错误的insert语句后,修正错误insert语句后再次执行它
18 insert into log_test values(88,'re_after');
19 end;
20 --commit;
21 end if;
22 end;
23 /
开始执行rollback to之后的代码
ORA-12899: 列 "SCOTT"."LOG_TEST"."LOGMAN" 的值太大 (实际值: 17, 最大值: 10)-12899
//直接在本会话查询log_test的记录,发现没有两个记录,就是没有了
//insert into other_log values(2,'zxz')的相关记录,因为代码块有rollback to,这就是//它的作用
PL/SQL procedure successfully completed
SQL> select * from log_test;
SEQ LOGMAN
--------------------------------------- ----------
88 re_after
1 zxy