sql - 处理 PL-SQL 异常并继续循环

标签 sql plsql oracle11g

接下来的 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;

当程序发现比预期的 trought subsrt 函数多的行时,返回

6502 : 65000 : java.sql.SQLException: ORA-06502: PL/SQL: numeric or value error: character string buffer too small ORA-06512: at line 1



id 不只是查找有问题的数据并将其添加到 XXW_PAYMENTS_F_EXCEPTION,而是喜欢处理异常并继续循环。

我想知道是否有我可以使用的“跳过”实现。我试过标记循环,但我得到了“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.

关于sql - 处理 PL-SQL 异常并继续循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48467966/

相关文章:

c# - 建立中央 SqlConnection 的最佳方式

mysql - 删除 JSON 键中的前导和尾随空格

sql - 我应该对 NOT NULL 列有多自由?

sql - 如何自动终止事件 session ?

sql - 查询时间在 12 点之后的选定项目

sql - 如何进行多关键词搜索?

oracle - Oracle中base64binary的输入

sql - 在 Oracle SQL 中,单竖线字符 ( '|') 的用途是什么?

java - Oracle jdbc 驱动程序 : implicit statement cache or setPoolable(true)?

database - 将迭代的提取替换为 BULK COLLECT