处理PL-SQL异常并继续循环
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了处理PL-SQL异常并继续循环相关的知识,希望对你有一定的参考价值。
下一个PL-SQL代码处理bloob对象,直到找到异常的bloob结构:
DECLARE
CURSOR c_mnu
IS
SELECT tb.payment_number,tb.blob_obj,tb.blob_size,tb.blob_id
FROM XXW_PYMNT_ITM_TRF_STG tb
where tb.payment_number not in (SELECT PAYMENT_NUMBER FROM XXW_PAYMENTS_F_EXCEPTION);
test_vc VARCHAR2(32767);
offset NUMBER := 1;
amount NUMBER := 1;
LEN NUMBER := 1;
idItem VARCHAR2(100);--id item de pago
montoAplicar VARCHAR2(100);--monto a aplicar
billItem VARCHAR2(60);--id de billing
blob_id_ant NUMBER ;-- blob id anterior
seq_num NUMBER := 0; -- sequencia agrupando por blob id
pago varchar(50);
BEGIN
FOR cu IN c_mnu
LOOP
LEN :=cu.blob_size;--tamaño del blob
test_vc := cu.blob_obj;--variable de trabajo del blob
pago := cu.payment_number;
WHILE ( LEN > 0)
LOOP
-- Verifico si es el mismo blob id al anterior
IF blob_id_ant = cu.blob_id THEN
seq_num := seq_num + 1;
ELSE
seq_num := 1;
END IF;
--Segundo LF
idItem:=substr(test_vc,instr(test_vc, ' ' , 1,10 )+1,(instr(test_vc, ' ' , 1,11)-(instr(test_vc, ' ' , 1,10 )+1)));
-- Tercer LF
montoAplicar:=substr(test_vc,instr(test_vc, ' ' , 1,15 )+1,(instr(test_vc, chr(10) , 1,3)-(instr(test_vc, ' ' , 1,15 )+1)));
--Cuarto LF
billItem:=substr(test_vc,instr(test_vc, '"' , 1 )+1,((instr(test_vc, chr(10) , 1,4 )-1)-(instr(test_vc, '"' , 1 )+1)));
amount:=instr(test_vc, chr(10) , 1,4 );
offset := amount+1;
--saco el pedazo de blob procesado
test_vc := substr(test_vc,offset, LEN);
--inserto los valores en la tabla de payments
insert into XXW_PYMNT_ITM_AMNT values (cu.payment_number,to_number(idItem),billItem,to_number(montoAplicar),cu.blob_id, seq_num);
--actualizo la longitud de blob
LEN := LEN - offset;
blob_id_ant := cu.blob_id;
END LOOP;
END LOOP;
commit;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line ( 'Pago con error ' || pago);
END;
当程序通过substr函数找到比预期更多的行时,返回
6502:65000:java.sql.SQLException:ORA-06502:PL / SQL:数字或值错误:字符串缓冲区太小ORA-06512:第1行
而不只是找到麻烦的数据并将其添加到XXW_PAYMENTS_F_EXCEPTION,id喜欢处理异常并继续循环。
我想知道是否有一个我可以使用的“SKIP”实现。我试过标记循环,但我得到了“PLS-00375:非法的GOTO声明;这个GOTO无法分支到标签”。有什么建议?谢谢。
答案
您可以在substr行周围创建一个新块,并在那里捕获异常,以便您保持循环。这是一个带有异常处理程序的内部块的简单示例。
>DECLARE
2 CURSOR testc
3 IS
4 SELECT table_name from user_tables where rownum < 5;
5 dummy number;
6 BEGIN
7 FOR testr IN testc
8 LOOP
9 BEGIN
10 select 1/0 into dummy from dual;
11 EXCEPTION
12 WHEN OTHERS THEN
13 dbms_output.put_line('Inner exception');
14 END;
15 END LOOP;
16 EXCEPTION
17 WHEN OTHERS THEN
18 dbms_output.put_line('Outer exception');
19 END;
20 /
Inner exception
Inner exception
Inner exception
Inner exception
PL/SQL procedure successfully completed.
另一答案
除了在异常后继续的问题,如果你想跳到下一个迭代,你可以使用continue
:
begin
for r in (
select 'X' as sometext from dual union all
select 'XY' from dual union all
select 'XYZ' from dual union all
select 'Z' from dual
)
loop
if length(r.sometext) > 2 then
dbms_output.put_line('(Skipping ' || r.sometext ||')');
continue;
end if;
dbms_output.put_line(r.sometext);
end loop;
end;
输出:
X
XY
(Skipping XYZ)
Z
或者没有if
:
begin
for r in (
select 'X' as sometext from dual union all
select 'XY' from dual union all
select 'XYZ' from dual union all
select 'Z' from dual
)
loop
continue when length(r.sometext) > 2;
dbms_output.put_line(r.sometext);
end loop;
end;
以上是关于处理PL-SQL异常并继续循环的主要内容,如果未能解决你的问题,请参考以下文章
Java - 在 for 循环中使用“继续”时出现未处理的异常错误?