PL/SQL中的几种异常处理方法

原创 2003年05月20日 12:32:00

这是Pona的文章,我斗胆将其贴上来,Pona不要介意哦!^_^

 

PL/SQL里,有三种方法可以在处理大批量数据时不会因为一条或几条数据错误而导致异常中止程序。

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

1、用Fetch into a cursor%TYPE把要处理的数据放到记录集里。当一条数据不符条件时,用标签<<NEXT_RECORD>>和GOTO NEXT_RECORD跳转语句使程序忽略这一条,转到下一条继续处理。

-------------------------------------------------------------------------------

-- Function Name     :  CalculateImportCharge

-- Function Desc     :  Calculate Import Charge

-- Created by        :  Author

-- Created Date      :  2003-05-16

-------------------------------------------------------------------------------

    FUNCTION CalculateImportCharge (

        p_i_job_id        IN VARCHAR2,

        p_i_as_of_date_id IN VARCHAR2) RETURN NUMBER

    AS

        CURSOR cur_ShipBlHeader IS

            SELECT import_folder_no

            FROM GMY_SHIP_BL_HEADER

            WHERE CANCEL_FLG = GMY_GA000_PKG.BL_CANCEL_FLG_OFF;

        rec_ShipBlHeader        cur_ShipBlHeader%ROWTYPE;

    BEGIN

        OPEN cur_ShipBlHeader;

        FETCH cur_ShipBlHeader INTO rec_ShipBlHeader;

        WHILE cur_ShipBlHeader%FOUND <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />LOOP

            x_num_error_code := GMY_GA000_PKG.CheckValidMasterBlNo (

                p_i_job_id,

                p_i_as_of_date_id,

                rec_ShipBlHeader.import_folder_no,

                x_vch_message);

            IF x_num_error_code

                IN (GMY_GA000_PKG.gn#NG, GMY_GA000_PKG.INVALID_BL_NO) THEN

                x_vch_message :=

                        p_i_job_id

                       || ' WARNING: Function CheckValidMasterBlNo @'

                       || ' Import folder '

                       || rec_ShipBlHeader.import_folder_no

                       || ' - Invalid BL No.';

                COM_LOG.PUTLINE (p_i_job_id, x_vch_message);

                GOTO NEXT_RECORD;

            END IF;

            x_num_error_code := CheckExistsOfAccDate (

                p_i_job_id,

                p_i_as_of_date_id,

                rec_ShipBlHeader.import_folder_no);

            IF x_num_error_code = GMY_GA000_PKG.gn#NG THEN

                GOTO NEXT_RECORD;

            END IF;

            COMMIT;

            <<NEXT_RECORD>>

            FETCH cur_ShipBlHeader INTO rec_ShipBlHeader;

        END LOOP;

        CLOSE cur_ShipBlHeader;

        RETURN GMY_GA000_PKG.gn#OK;

    EXCEPTION

        WHEN OTHERS THEN

            x_vch_message :=

                    p_i_job_id

                 || ' ERROR:   Function CalculateImportCharge @ '

                 || SUBSTR (SQLERRM (SQLCODE), 1, 100);

            COM_LOG.PUTLINE (p_i_job_id, x_vch_message);

            RETURN GMY_GA000_PKG.gn#NG;

END CalculateImportCharge;

2、当使用the Cursor FOR Loop循环时,在Loop循环里,把会出问题的情况写进一个独立的block块中,这个块包括完整的begin、end部分及exception异常处理部分。这样即使一条数据出现异常,也会继续执行下一条。

-------------------------------------------------------------------------------

-- Function Name     : GenerateInsCostInfRec

-- Function Desc     : Generate records to transmit in INF table

-- Created by        : SISS(AP)

-- Created Date      : 2003-03-26

-- ----------------------------------------------------------------------------

    FUNCTION GenerateInsCostInfRec (

        p_i_job_id             IN       VARCHAR2,

        p_i_as_of_date_id      IN       VARCHAR2) RETURN NUMBER

    AS

        CURSOR cur_cost IS

            SELECT cost.ROWID costRowId,

                   cost.import_folder_no,,

                   cost.insur_trans_id

            FROM GMY_COST_BL cost,

                 GMY_COMMON_MST mst

            WHERE cost.import_folder_no=invheader.import_folder_no

            AND cost.billing_amt_num IS NOT NULL

            AND cost.billing_amt_num!=0

            AND cost.insur_db_cr!=0;

    BEGIN

        FOR rec_cost IN cur_cost LOOP

            BEGIN

                x_num_ret_value := GMY_GA000_PKG.CheckValidMasterBlNo(

                                p_i_job_id,

                                p_i_as_of_date_id,

                                rec_cost.import_folder_no,

                                x_vch_error_msg);

                IF x_num_ret_value = GMY_GA000_PKG.VALID_BL_NO THEN

                    INSERT INTO GMY_COST_INS_INF(

                        cost_trx_id,,

                        created_by,

                        program_name)

                    VALUES(

                        GMY_COST_INS_INF_S.NEXTVAL,

                        PRG_NAME,

                        PRG_NAME);

                ELSIF x_num_ret_value = GMY_GA000_PKG.INVALID_BL_NO THEN

                    x_vch_error_msg := p_i_job_id

                        || ' Import folder '

                        || rec_cost.import_folder_no

                        || ' has repeated BL No. with other import folder.'

                        || ' Failed in insurance cost transmission.';

                    COM_LOG.PUTLINE(p_i_job_id, x_vch_error_msg);

                END IF;

            EXCEPTION

                WHEN OTHERS THEN

                    IF SQL%ROWCOUNT > 0 THEN  -- check for 'too many rows'

                       x_vch_error_msg := p_i_job_id||' '||

                           SUBSTR(SQLERRM(SQLCODE),1,100);

                       COM_LOG.PUTLINE(p_i_job_id, x_vch_error_msg);

                    ELSE

                       x_vch_error_msg := p_i_job_id||' '||

                           SUBSTR(SQLERRM(SQLCODE),1,100);

                       COM_LOG.PUTLINE(p_i_job_id, x_vch_error_msg);

                END IF;

            END;

        END LOOP;

        COMMIT;

        RETURN GMY_GA000_PKG.gn#OK;

    EXCEPTION

      WHEN OTHERS THEN

          x_vch_error_msg := p_i_job_id||' '||SUBSTR(SQLERRM(SQLCODE),1,100);

          COM_LOG.PUTLINE(p_i_job_id, x_vch_error_msg);

          ROLLBACK;

          RETURN GMY_GA000_PKG.gn#NG;

END GenerateInsCostInfRec;

3、当使用the Cursor FOR Loop循环时,在Loop循环里,把会出问题的情况拆分成子函数,分别处理。

----------------------------------------------------------------------------

-- Function Name      :  CopyDsToActualDs

-- Function Desc      :  Copy the records from DS DB to Actual DS DB.

-- Created by         :  Author

-- Created Date       :  2003-02-20

----------------------------------------------------------------------------

   FUNCTION CopyDsToActualDs (

        p_i_job_id         IN   VARCHAR2,

        p_i_as_of_date_id  IN   VARCHAR2)  RETURN NUMBER

    IS

        CURSOR cur_DsScc IS

            SELECT *

            FROM   GMY_DS_SCC;

    BEGIN

        FOR rec_DsHead IN cur_DsScc LOOP

            x_num_error_code := InsToActualScc(

                        p_i_job_id,

                        p_i_as_of_date_id,

                        rec_DsHead.order_by_code,

                        rec_DsHead.po_code,

                        rec_DsHead.wh);

        END LOOP;

    EXCEPTION

        WHEN OTHERS THEN

            x_vch_error_msg := p_i_job_id

                ||' Function Name: CopyDsToActualDs';

            COM_LOG.PUTLINE(p_i_job_id,x_vch_error_msg);

            x_vch_error_msg:=p_i_job_id||' '||SUBSTR(SQLERRM(SQLCODE),1,100);

            COM_LOG.PUTLINE(p_i_job_id, x_vch_error_msg);

            ROLLBACK;

        RETURN GMY_GA000_PKG.gn#NG;

    END CopyDsToActualDs;

----------------------------------------------------------------------------

-- Function Name      :  InsToActualScc

-- Function Desc      :  Deal with insert section.

-- Created by         :  Author

-- Created Date       :  2003-03-13

----------------------------------------------------------------------------

    FUNCTION InsToActualScc(

        p_i_job_id                      IN       VARCHAR2,

        p_i_as_of_date_id               IN       VARCHAR2,

        p_i_order_by_code               IN       VARCHAR2,

        p_i_po_code                     IN       VARCHAR2,

        p_i_wh                          IN       VARCHAR2

    ) RETURN NUMBER

    IS

        x_vch_error_msg VARCHAR2(255);

    BEGIN

        INSERT INTO GMY_ACTUAL_DS_SCC(

                order_by_code,

                po_code,

                wh )

        VALUES( p_i_order_by_code,

                p_i_po_code,

                p_i_wh);

        COMMIT;

        RETURN GMY_GA000_PKG.gn#OK;

    EXCEPTION

        WHEN OTHERS THEN

            x_vch_error_msg := p_i_job_id||' Function Name: InsToActualScc';

            COM_LOG.PUTLINE(p_i_job_id,x_vch_error_msg);

            x_vch_error_msg := p_i_job_id

                ||' The key of the record that failed to insert is: ';

            COM_LOG.PUTLINE(p_i_job_id,x_vch_error_msg);

            ROLLBACK;

        RETURN GMY_GA000_PKG.gn#NG;

    END InsToActualScc;

Oracle数据库之PL/SQL异常处理

Oracle数据库之PL/SQL异常处理异常指的是在程序运行过程中发生的异常事件,通常是由硬件问题或者程序设计问题所导致的。PL/SQL程序设计过程中,即使是写得最好的程序也可能会遇到错误或未预料到的...
  • zhliro
  • zhliro
  • 2015年06月14日 22:21
  • 1161

Java中的常用异常处理方法

觉得自己是一个Java专家吗?是否肯定自己已经全面掌握了Java的异常处理机制?在下面这段代码中,你能够迅速找出异常处理的六个问题吗? 1 OutputStreamWriter out =...
  • msyqmsyq
  • msyqmsyq
  • 2016年05月26日 09:50
  • 10733

springMVC三种异常处理方式

Spring MVC处理异常有3种方式:  (1)使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver;  (2)实现Spring的异常处理接口...
  • psp0001060
  • psp0001060
  • 2016年03月27日 16:40
  • 4843

有关于ORACLE PL/SQL异常处理的3个知识点!

  • 2008年10月17日 15:32
  • 5KB
  • 下载

源码-PL/SQL从入门到精通-第十二章-异常处理机制-Part 1

相比Java的异常处理功能,PL/SQL的异常处理结构上更为简单,容易理解。 在调试PL/SQL代码的过程中,已经领教过很多异常了,所以这章感觉不难。 --第12章开始 --代码12.1 编译时P...
  • hpdlzu80100
  • hpdlzu80100
  • 2016年07月21日 10:18
  • 384

Oracle PL/SQL开发基础(第二十九弹:异常处理简介)

异常处理简介Oracle中的错误可以分为如下两大类: - 编译时错误:程序在编写过程中出现的错误。PL/SQL引擎在进行编译时会发现这些错误并报告给用户,此时程序还没有完全运行。 - 运行时错误:...
  • lianjiww
  • lianjiww
  • 2017年08月09日 22:29
  • 200

PL/SQL 异常处理

1.预定义异常    对于系统预定义异常,用户无需在程序中定义,它们将由Oracle自动引发。    1.1如下:如果用户试图使用完全相同的主键值向同一表中插入两条记录,则系统会产生违反主键的异常,O...
  • linhaiyun_ytdx
  • linhaiyun_ytdx
  • 2017年04月15日 10:09
  • 210

【DB.PL/SQL】程序流程控制 —— 异常处理

如果PL/SQL 发生了一个错误,无论是系统错误还是应用的错误,都会抛出一个异常。当前PL/SQL块中执行单元就会暂定处理,如果当前块有一个异常处理单元的话,...
  • robinjwong
  • robinjwong
  • 2014年10月15日 16:33
  • 519

PL/SQL:异常处理

异常处理 语法:   EXCEPTION     WHEN EXCEPTION_NAME THEN       ;  END;   --必须紧挨着end! 例子:除数为0 declare  ...
  • crzzyracing
  • crzzyracing
  • 2017年07月19日 09:49
  • 252

PL/SQL中的异常处理

PL/SQL程序在运行的过程当中,可能会出现错误或者异常的情况,例如无法建立与ORACLE的连接,或者返回多行的错误。好的程序应该是对可能发生的异常情况进行处理,异常处理代码在EXCEPTION中实现...
  • ziwen00
  • ziwen00
  • 2011年04月04日 22:09
  • 737
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:PL/SQL中的几种异常处理方法
举报原因:
原因补充:

(最多只允许输入30个字)