0

其动机是即使在发生异常后也保持程序运行。

我有一个用于处理提要(文本)文件的代码。

当它遇到异常时,它会将其记录到临时错误表中并尝试回滚到代码中前面所述的保存点。

但是,我想跳过其中有错误的行并继续执行过程。这是代码片段。

    CREATE OR REPLACE
    PROCEDURE ABC AS
    FHANDLE UTL_FILE.FILE_TYPE;
    BUFFER VARCHAR2(32767);
    ROW_NO NUMBER;
    ERROR_CODE VARCHAR2(50);
    ERROR_MSG VARCHAR2(299);
    CUST_ID TABLE1.CUSTOMER_ID%TYPE;
    B_ACCOUNT_NO TABLE1.BILLING_ACCOUNT_NO%TYPE;
    UB_OUT TABLE1.OUTSTANDING_UNBILLED_AMOUNT%TYPE;
    BA_COUNT NUMBER;
    DEL1 NUMBER;
    DEL2 NUMBER;
    DEL3 NUMBER;
    BEGIN
    FHANDLE := UTL_FILE.FOPEN('DIR1','FILENAME.txt','R',4096);
    ROW_NO := 0;
    ERROR_CODE:= '';
    ERROR_MSG := '';
    LOOP
    BEGIN
    UTL_FILE.GET_LINE(FHANDLE,BUFFER);
    EXCEPTION
    WHEN NO_DATA_FOUND THEN
    EXIT;
    END;
    SAVEPOINT S1;
    --GETTING DELIMITER POSITIONS
    DEL1 := INSTR(BUFFER,'|',1,1);
    DEL2 := INSTR(BUFFER,'|',1,2);
    DEL3 := INSTR(BUFFER,'|',1,3);
    ROW_NO := ROW_NO +1 ;
    --RETRIEVING DATA FROM TEXT FILE INTO VARIABLES
    B_ACCOUNT_NO := SUBSTR(BUFFER,1,DEL1-1);
    CUST_ID := SUBSTR(BUFFER,DEL1+1,DEL2-DEL1-1);
    UB_OUT := SUBSTR(BUFFER,DEL2+1);
    --CHECK FOR PRESENCE OF BILLING ACCOUNT
    SELECT COUNT(BILLING_ACCOUNT_NO) INTO BA_COUNT FROM TABLE1 WHERE  CUSTOMER_ID = CUST_ID AND BILLING_ACCOUNT_NO = B_ACCOUNT_NO;
    --IF PRESENT THEN UPDATE
    IF BA_COUNT != 0
    THEN
    UPDATE TABLE1
    SET OUTSTANDING_UNBILLED_AMOUNT = UB_OUT
    WHERE BILLING_ACCOUNT_NO = B_ACCOUNT_NO AND CUSTOMER_ID = CUST_ID;
    ELSE
    INSERT INTO TABLE1(CUSTOMER_ID,BILLING_ACCOUNT_NO,OUTSTANDING_BILLED_AMOUNT,OUTSTANDING_UNBILLED_AMOUNT)
VALUES(CUST_ID,B_ACCOUNT_NO,0,UB_OUT);
    END IF;
    END LOOP;
    DBMS_OUTPUT.PUT_LINE('TOTAL_ROWS_READ : '||ROW_NO);
    UTL_FILE.FCLOSE(FHANDLE);
    EXCEPTION
    WHEN NO_DATA_FOUND THEN
    ERROR_CODE := SQLCODE;
    ERROR_MSG := SQLERRM;
    CWSC_ERROR_PROC(ERROR_CODE,ERROR_MSG,ROW_NO,CUST_ID,B_ACCOUNT_NO,'','');
    WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('OTHERS EXCEPTION');
    --log into error table
    ERROR_CODE := SQLCODE;
    ERROR_MSG := SQLERRM;
    --THIS PROCEDURE LOGS ERRORS INTO TEMPORARY ERROR LOG TABLE
    ERROR_PROC(ERROR_CODE,ERROR_MSG,ROW_NO,CUST_ID,B_ACCOUNT_NO,'','');
    ROLLBACK TO S1;

   << NEED CODE HERE TO SKIP CURRENT RECORD AND START EXECUTION FROM NEXT RECORD >>      

    END ABC;

文本文件有点像

1002207577 | 1002207576 | 0
1002201449 | 1002201446 | 0
1000000010 | 1000000010 | 0
1000000018 | 1000000098 | 0
1000000023 | 1000000073 | 0
4

1 回答 1

1

您应该创建内部BEGIN - EXCEPTION - END块并将您的代码和异常处理程序放在那里。在这种情况下,您将只完成内部块并继续外部

例子:

DECLARE
  n NUMBER;
BEGIN
  DBMS_OUTPUT.PUT_LINE('First n='||n);
  BEGIN
    n:= 'Hello';
  EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('Not a number');
  END;
  DBMS_OUTPUT.PUT_LINE('Finally n='||n);
END;
于 2015-12-09T08:14:21.247 回答