如何为循环编写异常?

Posted

技术标签:

【中文标题】如何为循环编写异常?【英文标题】:How to write exception for a loop? 【发布时间】:2015-01-15 21:58:02 【问题描述】:
create or replace PROCEDURE BBVA_SP_MIGRATE_CEG 
(
    --parameter pass
    x_migration_status          OUT         varchar2    
) AS 
    --variable declarations
    v_contract_number                       kndtctc.tctc_cncclipu%type;
    v_customer_code                         kndtcct.tcct_cncctco%type;
    v_customer_name                         varchar2(50);
    v_customer_number                       varchar2(50);
    v_account_number                        varchar2(50);
    v_contact_name                          varchar2(50);
    v_phone_number                          varchar2(25);
    v_email_id                              varchar2(50);
    v_connection_type                       varchar2(50);
    v_LBX_OUT1                      varchar2(10);
    v_LBX_OUT2                      varchar2(10);
    v_LBX_OUT3                      varchar2(10);
    v_LBX_OUT4                      varchar2(10);
    v_LBX_OUT5                      varchar2(10);
    v_LBX_OUT6                      varchar2(10);
    v_LBX_OUT7                      varchar2(10);
    v_LBX_OUT8                      varchar2(10);
    v_LBX_OUT9                      varchar2(10);
    v_STOPFILE_IN1                  varchar2(10);
    v_ARP_OUT1                      varchar2(10);
    v_ARP_OUT2                      varchar2(10);
    v_ARP_OUT3                      varchar2(10);
    v_ARP_OUT4                      varchar2(10);
    v_ARP_OUT5                      varchar2(10);
    v_ARP_OUT6                      varchar2(10);
    v_ARP_OUT7                      varchar2(10);
    v_ARP_OUT8                      varchar2(10);
    v_ARP_OUT9                      varchar2(10);
    v_ARP_IN1                       varchar2(10);
    v_ARP_IN2                       varchar2(10);
    v_ARP_IN3                       varchar2(10);
    v_ARP_IN4                       varchar2(10);
    v_ARP_IN5                       varchar2(10);
    v_ARP_IN6                       varchar2(10);
    v_ARP_IN7                       varchar2(10);
    v_ARP_IN8                       varchar2(10);
    v_ARP_IN9                       varchar2(10);
    v_ACH_OUT1                      varchar2(10);
    v_ACH_OUT2                      varchar2(10);
    v_ACH_OUT3                      varchar2(10);
    v_ACH_OUT4                      varchar2(10);
    v_ACH_OUT5                      varchar2(10);
    v_ACH_OUT6                      varchar2(10);
    v_ACH_OUT7                      varchar2(10);
    v_ACH_OUT8                      varchar2(10);
    v_ACH_OUT9                      varchar2(10);
    v_ACH_IN1                       varchar2(10);
    v_ACH_IN2                       varchar2(10);
    v_ACH_IN3                       varchar2(10);
    v_ACH_IN4                       varchar2(10);
    v_ACH_IN5                       varchar2(10);
    v_ACH_IN6                       varchar2(10);
    v_ACH_IN7                       varchar2(10);
    v_ACH_IN8                       varchar2(10);
    v_ACH_IN9                       varchar2(10);
    v_ANL822FILE_OUT1               varchar2(10);
    v_DEPOSITRACKFILE_OUT1          varchar2(10);
    v_EDI_OUT1                      varchar2(10);
    v_CDA_OUT1                      varchar2(10);
    v_BAI_OUT1                      varchar2(10);
    v_ICL_IN1                       varchar2(10);
    v_RECONFILE_OUT1                varchar2(10);
    v_SUSPENDCARDFILE_IN1           varchar2(10);
    V_ceg_record_found              varchar2(1);
    v_REC_NUMBER                    number;
    V_BANKCODE                      varchar2(25);
    v_status                        varchar2(10); 
    v_timestamp                     TIMESTAMP(6):=systimestamp;
    v_tx                  VARCHAR2(2000);
    v_sysdate             DATE := SYSDATE;
    v_tz                  varchar2(2000);
    v_num_err             exception;
BEGIN 
  v_tx:=to_char(v_timestamp,'DD-MON-RR HH.MI.SSXFF AM');
  v_tz:=to_char(v_sysdate, 'DD-MON-RR');

  x_migration_status:='FAIL';
  V_ceg_record_found:='N';

<<outer_loop>>
for in_rec_number IN 1..500 LOOP

SELECT  CUSTOMERNAME, 
        CUSTOMERNUMBER,
        ACCOUNTNUMBER,
              CONTACTNAME,
              CONTACTPHONE,
              CONTACTEMAIL, 
              CONNECTIONTYPE,
              LBX_OUT1,
              LBX_OUT2,
              LBX_OUT3,
              LBX_OUT4,
              LBX_OUT5,
              LBX_OUT6,
              LBX_OUT7,
              LBX_OUT8,
              LBX_OUT9,
              STOPFILE_IN1,
              ARP_OUT1,
              ARP_OUT2,
              ARP_OUT3,
              ARP_OUT4,
              ARP_OUT5,
              ARP_OUT6,
              ARP_OUT7,
              ARP_OUT8,
              ARP_OUT9,
              ARP_IN1,
              ARP_IN2,
              ARP_IN3,
              ARP_IN4,
              ARP_IN5,
              ARP_IN6,
              ARP_IN7,
              ARP_IN8,
              ARP_IN9,
              ACH_OUT1,
              ACH_OUT2,
              ACH_OUT3,
              ACH_OUT4,
              ACH_OUT5,
              ACH_OUT6,
              ACH_OUT7,
              ACH_OUT8,
              ACH_OUT9,
              ACH_IN1,
              ACH_IN2,
              ACH_IN3,
              ACH_IN4,
              ACH_IN5,
              ACH_IN6,
              ACH_IN7,
              ACH_IN8,
              ACH_IN9,
              ANL822FILE_OUT1,
              DEPOSITRACKFILE_OUT1,
              EDI_OUT1,
              CDA_OUT1,
              BAI_OUT1,
              ICL_IN1,
              RECONFILE_OUT1,
              SUSPENDCARDFILE_IN1,
              'Y', 
        CEG_ID,
        BANKCODE,
        CEG_STATUS

INTO 

    v_customer_name,                            
    v_customer_number,                          
    v_account_number,                           
    v_contact_name,                         
    v_phone_number,                             
    v_email_id,                                 
    v_connection_type,                      
    v_LBX_OUT1,                     
    v_LBX_OUT2,                     
    v_LBX_OUT3,                     
    v_LBX_OUT4,                     
    v_LBX_OUT5,                     
    v_LBX_OUT6,                     
    v_LBX_OUT7,                     
    v_LBX_OUT8,                     
    v_LBX_OUT9,                     
    v_STOPFILE_IN1,                 
    v_ARP_OUT1,                     
    v_ARP_OUT2,                     
    v_ARP_OUT3,                     
    v_ARP_OUT4,                     
    v_ARP_OUT5,                     
    v_ARP_OUT6,                     
    v_ARP_OUT7,                     
    v_ARP_OUT8,                     
    v_ARP_OUT9,                     
    v_ARP_IN1,                      
    v_ARP_IN2,                      
    v_ARP_IN3,                      
    v_ARP_IN4,                      
    v_ARP_IN5,                      
    v_ARP_IN6,                      
    v_ARP_IN7,                      
    v_ARP_IN8,                      
    v_ARP_IN9,                      
    v_ACH_OUT1,                     
    v_ACH_OUT2,                     
    v_ACH_OUT3,                     
    v_ACH_OUT4,                     
    v_ACH_OUT5,                     
    v_ACH_OUT6,                     
    v_ACH_OUT7,                     
    v_ACH_OUT8,                     
    v_ACH_OUT9,                     
    v_ACH_IN1,                      
    v_ACH_IN2,                      
    v_ACH_IN3,                      
    v_ACH_IN4,                  
    v_ACH_IN5,                      
    v_ACH_IN6,                      
    v_ACH_IN7,                      
    v_ACH_IN8,                      
    v_ACH_IN9,                      
    v_ANL822FILE_OUT1,                  
    v_DEPOSITRACKFILE_OUT1,          
    v_EDI_OUT1,                     
    v_CDA_OUT1,                     
    v_BAI_OUT1,                     
    v_ICL_IN1,                  
    v_RECONFILE_OUT1,       
    v_SUSPENDCARDFILE_IN1,          
    v_CEG_RECORD_FOUND,
  v_REC_NUMBER,
  V_BANKCODE,
  V_Status

FROM    t_ceg_migration
WHERE
       upper(CEG_STATUS) = 'RECEIVED'  and   
       in_rec_number     = to_number(CEG_ID);  

IF v_CEG_RECORD_FOUND = 'Y' THEN

DBMS_OUTPUT.PUT_LINE (in_rec_number);

--   get next sequence numbers
V_CONTRACT_NUMBER   :=  tctc_cncclipu_seq.nextval;
V_CUSTOMER_CODE := tcct_cncctco_seq.nextval;

--then inserts into other tables, not relevant to the exception--

x_migration_status := to_char(v_contract_number);


UPDATE t_Ceg_migration
set CEG_status = 'IMPORTED' 
where
       upper(CEG_STATUS) = 'RECEIVED'  and   
       in_rec_number     = to_number(CEG_ID);        

end if; -- ceg_record_found

这是我在所有更新应该发生在受此过程影响的其他表之后放置异常的地方。

 BEGIN
    IF v_rec_number > 500 THEN
    RAISE v_num_err;
    END IF;
    EXCEPTION
    WHEN v_num_err THEN
    dbms_output.put_line ('Error: Try Again');
    End;

    end LOOP outer_loop;
    END BBVA_SP_MIGRATE_CEG;

异常会去哪里以确保在运行异常之前显示有效记录?

【问题讨论】:

你能再展示一些你的上下文过程吗? 两行源码是不够的。请展示您的完整程序并描述它的数据。 variable dec: x_migration_status OUT varchar2 ) AS --variable declarations v_contract_number kndtctc.tctc_cncclipu%type; v_customer_code kndtcct.tcct_cncctco%type; v_customer_name varchar2(50); v_customer_number varchar2(50); v_account_number varchar2(50); 正文:开始 v_tx:=to_char(v_timestamp,'DD-MON-RR HH.MI.SSXFF AM'); v_tz:=to_char(v_sysdate, 'DD-MON-RR'); x_migration_status:='失败'; V_ceg_record_found:='N'; > for in_rec_number IN 1..500 LOOP SELECT CUSTOMERNAME、CUSTOMERNUMBER、ACCOUNTNUMBER、CONTACTNAME、CONTACTPHONE, 请将代码和重要的新信息放入问题中,而不是 cmets。 【参考方案1】:

您已将异常处理程序放在最后,这意味着一旦遇到异常,它就会退出循环并在最后的异常块中处理。如果您希望进程继续,则将异常处理程序本地添加到循环中的 SELECT 语句中。

PROCEDURE bbva_sp_migrate_ceg(x_migration_status OUT VARCHAR2 )
AS
  v_contract_number kndtctc.tctc_cncclipu%TYPE;
  v_customer_code kndtcct.tcct_cncctco%TYPE;
  v_customer_name   VARCHAR2(50);
  v_customer_number VARCHAR2(50);
  v_account_number  VARCHAR2(50);
BEGIN
  v_tx:=To_char(v_timestamp,'DD-MON-RR HH.MI.SSXFF AM');
  v_tz:=To_char(v_sysdate, 'DD-MON-RR');
  x_migration_status:='FAIL';
  v_ceg_record_found:='N';
  <<outer_loop>>
  FOR in_rec_number IN 1..500
  LOOP
    BEGIN
      SELECT customername,
             customernumber,
             accountnumber,
             contactname,
             contactphone,
      FROM   t_ceg_migration
      WHERE  upper(ceg_status) = 'RECEIVED'
      AND    in_rec_number = to_number(ceg_id);

      IF v_ceg_record_found = 'Y' THEN
        dbms_output.Put_line (in_rec_number); -- get next sequence numbers
        V_CONTRACT_NUMBER := tctc_cncclipu_seq.nextval; 
        V_CUSTOMER_CODE := tcct_cncctco_seq.nextval;
        x_migration_status := To_char(v_contract_number);

        UPDATE t_ceg_migration
        SET    ceg_status = 'IMPORTED'
        WHERE  upper(ceg_status) = 'RECEIVED'
        AND    in_rec_number = to_number(ceg_id);

      END IF; -- ceg_record_found
    EXCEPTION
    WHEN no_data_found THEN
      dbms_output.Put_line ('No data found for: '
      || v_contract_number);
    WHEN OTHERS THEN
      dbms_output.Put_line ('Error for : '
      || v_contract_number);
      dbms_output.Put_line(dbms_utility.format_error_backtrace);
    END
  END LOOP outer_loop;
END bbva_sp_migrate_ceg;

这样,如果循环的特定迭代出现一些错误,异常会被捕获、处理,错误消息写入缓冲区,然后它会继续循环的下一次迭代

在相关说明中,强烈建议您将错误写入表而不是缓冲区/

【讨论】:

@AlexPoole 哎呀,你本来想早点删除它们,但忘了。

以上是关于如何为循环编写异常?的主要内容,如果未能解决你的问题,请参考以下文章

R如何为循环编写双精度并将结果存储在矩阵中

如何为异常中的特定错误消息编写if语句? [重复]

如何为事务管理编写自定义过滤器

如何为调用 API 的方法编写 JUnit 测试?

如何为需要 4 个数字输入的 C 程序编写 Bash 脚本? [复制]

如何为 graphql 创建自定义错误/异常处理程序?