【问题标题】:error in all 3 exception block of pl/sqlpl/sql 的所有 3 个异常块中的错误
【发布时间】:2015-12-28 14:08:53
【问题描述】:
CREATE OR REPLACE 
PROCEDURE   "p*_d******"
(V_Day IN CHAR, v_Pk_List IN CHAR, 
                v_Log OUT VARCHAR2, v_Msg OUT VARCHAR2)

is 
--v_Pk_List       VARCHAR2(50); 
v_DSQL1        VARCHAR2(2000);
v_DSQL2        VARCHAR2(2000);
V_COUNT        NUMBER(10);
V_Today_Day    VARCHAR2(20);
V_START_TS     TIMESTAMP(2);
v_Errormsg     VARCHAR2(100);
V_PK           NUMBER(10);

CURSOR pk_cur IS 
SELECT   *
FROM   (    SELECT   TRIM (REGEXP_SUBSTR (num_csv,
                                            '[^,]+',
                                            1,
                                            LEVEL))
                                          num_value
            FROM   (    SELECT   v_Pk_List num_csv FROM DUAL)
            CONNECT BY   LEVEL <= regexp_count (num_csv, ',', 1) + 1)
 WHERE   num_value IS NOT NULL;

BEGIN

SELECT TO_CHAR(SYSTIMESTAMP, 'DD-MON-YY HH:MI:SS AM') INTO V_START_TS FROM DUAL;

    IF

    NOT pk_cur%ISOPEN THEN 
        OPEN pk_cur; 
    END IF; 
 BEGIN    
  LOOP 

     FETCH pk_cur INTO V_PK; 
     EXIT WHEN pk_cur%NOTFOUND; 

     SELECT COUNT(*) 
     INTO V_COUNT 
     FROM 
     ***_***_****** 
     WHERE 
     RUN_MODE =V_DAY
     AND PK_ID=V_PK;
  IF 
     V_COUNT<=0 THEN 

EXECUTE IMMEDIATE 'INSERT INTO ***_***_******
           (
            fact********,
            PK_ID,
            pr**_d*****,
            RUN_MODE,
            CREATE_DATE
           )
            SELECT fact********,
            PK_ID,
            DUEDATE,
            '''||V_DAY||''',
            SYSTIMESTAMP
            FROM ***_***_*********
            WHERE PK_ID ='''||V_PK||'''';


  v_Errormsg :='INSERT SUCCESSFULL FOR';--||V_DAY||'AND PK_ID'||V_PK;

  EXECUTE IMMEDIATE 'INSERT INTO u**_s*****_e***_l**(MODULENAME,PROCEDURENAME,PKID,MODELID,LEVELID,COL_1,COL_2,ERRORMSG,ERRORTRACE,START_TS,END_TS)
                           VALUES(''EMEA_PROCESS'',
                           ''p*_d******'',
                           '''||v_Pk_List||''',
                           NULL,
                           NULL,
                           ''SUCCESS'',
                           '''||DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||''',
                           NULL,
                           NULL,
                           '''||V_START_TS||''',
                           SYSTIMESTAMP)';
  BEGIN                          
  EXCEPTION WHEN OTHERS THEN 
  v_Errormsg := 'ERROR: p*_d****** PROCEDURE INSERT ERROR' ;--|| 'ERROR_MSG IS '||SQLERRM;
  EXECUTE IMMEDIATE 'INSERT INTO u**_s*****_e***_l**(MODULENAME,PROCEDURENAME,PKID,MODELID,LEVELID,COL_1,COL_2,ERRORMSG,ERRORTRACE,START_TS,END_TS)
                           VALUES(''????'',
                           ''p*_d******'',
                           '''||v_Pk_ID||''',
                           NULL,
                           NULL,
                           '''||v_Errormsg||''',
                           '''||DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||''',
                           NULL,
                           NULL,
                           '''||V_START_TS||''',
                           SYSTIMESTAMP)';
        END;                   
  END IF;


EXECUTE IMMEDIATE 'MERGE INTO ***_***_********* GFO
            USING 
            ***_***_****** UFD 
            ON (GFO.fact********=UFD.fact********)
            WHEN MATCHED THEN 
            UPDATE 
            SET 
            GFO.pr**_d*****=UFD.pr**_d*****
            WHERE UFD.CREATE_DATE IS NOT NULL
            AND UFD.RUN_MODE= '''||V_DAY||'''
            AND GFO.PK_ID='''||V_PK||'''';

  v_Errormsg :='pr**_d***** OF GFO UPDATED FOR ';--||V_DAY||' AND PK_ID '||V_PK;
   EXECUTE IMMEDIATE 'INSERT INTO u**_s*****_e***_l**(MODULENAME,PROCEDURENAME,PKID,MODELID,LEVELID,COL_1,COL_2,ERRORMSG,ERRORTRACE,START_TS,END_TS)
                           VALUES(''EMEA_PROCESS'',
                           ''p*_d******'',
                           '''||v_Pk_List||''',
                           NULL,
                           NULL,
                           ''SUCCESS'',
                           '''||DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||''',
                           NULL,
                           NULL,
                           '''||V_START_TS||''',
                           SYSTIMESTAMP)';

  BEGIN        
  EXCEPTION WHEN OTHERS THEN
  v_Errormsg := 'ERROR: p*_d****** PROCEDURE INSERT ERROR';-- || 'ERROR_MSG IS '||SQLERRM;
  EXECUTE IMMEDIATE 'INSERT INTO u**_s*****_e***_l**(MODULENAME,PROCEDURENAME,PKID,MODELID,LEVELID,COL_1,COL_2,ERRORMSG,ERRORTRACE,START_TS,END_TS)
                           VALUES(''????'',
                           ''p*_d******'',
                           '''||v_Pk_ID||''',
                           NULL,
                           NULL,
                           '''||v_Errormsg||''',
                           '''||DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||''',
                           NULL,
                           NULL,
                           '''||V_START_TS||''',
                           SYSTIMESTAMP)';
  END;

EXECUTE IMMEDIATE 'MERGE INTO ***_***_****** UFD
            USING
            ***_***_********* GFO
            ON (UFD.fact********=GFO.fact********)
            WHEN MATCHED THEN 
            UPDATE
            SET
            UFD.pr**_d*****=GFO.DUEDATE
            WHERE
            GFO.PK_ID='''||V_PK||'''';

  v_Errormsg :='pr**_d***** OF UFD BACKED UP IN GFO FOR ';--||V_DAY||' AND PK_ID '||V_PK;
  EXECUTE IMMEDIATE 'INSERT INTO u**_s*****_e***_l**(MODULENAME,PROCEDURENAME,PKID,MODELID,LEVELID,COL_1,COL_2,ERRORMSG,ERRORTRACE,START_TS,END_TS)
                           VALUES(''EMEA_PROCESS'',
                           ''p*_d******'',
                           '''||v_Pk_List||''',
                           NULL,
                           NULL,
                           ''SUCCESS'',
                           '''||DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||''',
                           NULL,
                           NULL,
                           '''||V_START_TS||''',
                           SYSTIMESTAMP)';

  BEGIN
  EXCEPTION WHEN OTHERS THEN
  v_Errormsg := 'ERROR: p*_d****** PROCEDURE INSERT ERROR';--||'ERROR_MSG IS '||SQLERRM;
   EXECUTE IMMEDIATE 'INSERT INTO u**_s*****_e***_l**(MODULENAME,PROCEDURENAME,PKID,MODELID,LEVELID,COL_1,COL_2,ERRORMSG,ERRORTRACE,START_TS,END_TS)
                           VALUES(''????'',
                           ''p*_d******'',
                           '''||v_Pk_ID||''',
                           NULL,
                           NULL,
                           '''||v_Errormsg||''',
                           '''||DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||''',
                           NULL,
                           NULL,
                           '''||V_START_TS||''',
                           SYSTIMESTAMP)';
    END;
    END LOOP; 
  END;
  END p*_d******;

我收到所有 3 个例外块的以下错误:

错误(100,3):PLS-00103:在预期以下情况之一时遇到符号“EXCEPTION”:(begin case declare exit for goto if loop mod null pragma raise return select update while with

【问题讨论】:

  • Exeption 语句不能作为开始结束块中的块的“开始”。我建议您阅读此(Oracle 文档,可通过 Google 轻松找到):docs.oracle.com/cd/A97630_01/appdev.920/a96624/07_errs.htm
  • 我不得不说,这是我一段时间以来见过的最“加星标”的代码。这些星号确实增加了它的不可读性。

标签: plsql oracle10g


【解决方案1】:

您的代码有很多问题。编译错误的直接原因是您的匿名块结构不正确:BEGIN 和 EXCEPTION 关键字之间必须有一些代码。您需要重新考虑您的异常处理,也许通过定义具有已执行代码和定制错误处理的块。

例如,对最后一段代码的重铸将两条带有定制错误消息的语句放在一个带有自己的异常部分的匿名块中:

BEGIN
    v_Errormsg := 'ERROR: p*_d****** PROCEDURE INSERT ERROR';--||'ERROR_MSG IS '||SQLERRM;
    EXECUTE IMMEDIATE 'MERGE INTO ***_***_****** UFD
            USING
            ....';
    v_Errormsg :='pr**_d***** OF UFD BACKED UP IN GFO FOR ';--||V_DAY||' AND PK_ID '||V_PK;
    EXECUTE IMMEDIATE 'INSERT INTO u**_s*****_e***_l**(MODULENAME,PROCEDURENAME,PKID,MODELID,LEVELID,COL_1,COL_2,ERRORMSG,ERRORTRACE,START_TS,END_TS)
                           VALUES(''EMEA_PROCESS'',
            ....';
EXCEPTION 
    WHEN OTHERS THEN
        EXECUTE IMMEDIATE 'INSERT INTO u**_s*****_e***_l**(MODULENAME,PROCEDURENAME,PKID,MODELID,LEVELID,COL_1,COL_2,ERRORMSG,ERRORTRACE,START_TS,END_TS)
                           VALUES(''????'',
        ...
END;

它将编译(可能,我不会尝试重新创建您的环境来测试它)。但这只能解决部分问题。

您的程序有很多重复,这总是一个不好的迹象。我们应该设计一个程序来重用通用功能,而不是依赖于剪切粘贴。

但最麻烦的一点是动态 SQL 的使用。这真的是不必要的。我们可以在普通 SQL 中使用 PL/SQL 变量。动态 SQL 很难正确处理,因为任何编译错误都会成为运行时错误。如果没有其他选择,我们应该只使用动态 SQL。

【讨论】:

  • 非常感谢APC..非常感谢....我在处理异常时遇到了问题......谢谢大家
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-28
  • 1970-01-01
  • 1970-01-01
  • 2016-04-11
  • 2017-04-12
  • 1970-01-01
相关资源
最近更新 更多