pl / sql

时间:2015-12-28 14:08:53

标签: plsql oracle10g

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个EXCEPTION块的跟随错误:

  

错误(100,3):PLS-00103:当遇到以下情况之一时遇到符号“EXCEPTION”:(如果使用&lt;&lt; continue,则开始情况声明退出goto if loop mod null pragma raise return select update close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe purge

1 个答案:

答案 0 :(得分: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。