【问题标题】:How can I call a procedure declared inside another procedure?如何调用在另一个过程中声明的过程?
【发布时间】:2019-10-04 19:10:52
【问题描述】:

我对 Db2 中的过程有疑问。我使用“CREATE PROCEDURE”创建了一个存储过程,其中我有另一个使用“DECLARE PROCEDURE”声明的存储过程。但是,这个由declare创建的过程,不能使用“CALL”来调用。

当我尝试运行该过程时,Db2 返回:

[代码:-440,SQL 状态:42884] DB2 SQL 错误:SQLCODE=-440, SQLSTATE=42884, SQLERRMC=DMTLDBR.SP_DASH_CALENDARIO.PROCURA_DIA_UTIL_POST_DIA1;程序, 驱动程序=4.25.1301

我应该如何调用声明的过程? (PROCURA_DIA_UTIL_POST_DIA1)

代码:

create or replace PROCEDURE           "SP_DASH_CALENDARIO" (IN P_MES INTEGER)
BEGIN

------
DECLARE SQLSTATE                       CHAR(5) DEFAULT ' ';

DECLARE V_ANO_MES                      DECIMAL(6); 
DECLARE V_ID_DIA                       ANCHOR DATA TYPE TO DMTLDBR.TB_DIM_DIADIA.ID_DIA;

DECLARE V_VAL_REAL_CAL                 ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_VENDASDIARIO.VAL_TONLIQUIDO;
DECLARE V_VAL_TONVNEMA                 ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_VENDASDIARIO.VAL_TONVNEMA;
DECLARE V_VAL_FAT357_CAL               ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_VENDASDIARIO.VAL_FAT357; 
DECLARE V_VAL_PERDA_FAT_CAL            ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_VENDASDIARIO.VAL_PERDA;

DECLARE V_SUM_VAL_REAL_CAL             ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_DASH_CALENDARIO.VAL_REAL_CAL;
DECLARE V_SUM_VAL_TONVNE_CAL           ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_DASH_CALENDARIO.VAL_TONVNE_CAL;
DECLARE V_SUM_VAL_TONLIQUIDO_ZBCL_CAL  ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_DASH_CALENDARIO.VAL_TONLIQUIDO_ZBCL_CAL;
DECLARE V_SUM_VAL_TONLIQUIDO_CAL       ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_DASH_CALENDARIO.VAL_TONLIQUIDO_CAL;
DECLARE V_SUM_VAL_FAT357_CAL           ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_DASH_CALENDARIO.VAL_FAT357_CAL;   

DECLARE V_VAL_TONLIQUIDO_CAL           ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_DASH_CALENDARIO.VAL_TONLIQUIDO_CAL;
DECLARE V_VAL_TONVNE_CAL               ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_DASH_CALENDARIO.VAL_TONVNE_CAL;
DECLARE V_VAL_TONLIQUIDO_ZBCL_CAL      ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_DASH_CALENDARIO.VAL_TONLIQUIDO_ZBCL_CAL; 

DECLARE V_VAL_PLANO_FAT_CAL            ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_PLANEJ_MAN.VAL_PLANO; 
DECLARE V_VAL_PLANO                    ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_PLANEJ_MAN.VAL_PLANO; 
DECLARE V_TOTAL_PLANO_DESOVA_SEMANAL   ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_PLANEJ_MAN.TOTAL_PLANO_DESOVA_SEMANAL;

DECLARE V_ID_DIASEMANA                 ANCHOR DATA TYPE TO DMTLDBR.TB_DIM_DIADIA.ID_DIASEMANA;
DECLARE V_FLG_HOLIDAY                  ANCHOR DATA TYPE TO DMTLDBR.TB_DIM_DIADIA.FLG_HOLIDAY;

DECLARE V_IND_LEGENDA                  DECIMAL(1);
DECLARE V_VARIANTE                     ANCHOR DATA TYPE TO DMTLDBR.TB_DIM_PRODVARIANTE.ID_VARIANTE;

DECLARE V_VAL_PERDA                    ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_VENDASDIARIO.VAL_TONLIQUIDO;
DECLARE V_VAL_DESOVA                   ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_VENDASDIARIO.VAL_TONLIQUIDO;
DECLARE V_VAL_UHT                      ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_VENDASDIARIO.VAL_TONLIQUIDO;
DECLARE V_VAL_SUCO                     ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_VENDASDIARIO.VAL_TONLIQUIDO;
DECLARE V_VAL_REQ                      ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_VENDASDIARIO.VAL_TONLIQUIDO;
DECLARE V_FAT_UHT                      ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_VENDASDIARIO.VAL_FAT357;  
DECLARE V_FAT_REQ                      ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_VENDASDIARIO.VAL_FAT357; 


DECLARE V_ID_DIA_INI                   ANCHOR DATA TYPE TO DMTLDBR.TB_DIM_DIADIA.ID_DIA;
DECLARE V_ID_DIA_FIM                   ANCHOR DATA TYPE TO DMTLDBR.TB_DIM_DIADIA.ID_DIA;
DECLARE FLAG_DIA_UTIL                  BOOLEAN;
DECLARE V_SUM_VAL_TONVNEMA_CAL         ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_DASH_CALENDARIO.VAL_TONVNEMA_CAL;
DECLARE V_SUM_VAL_FAT357               ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_VENDASDIARIO.VAL_FAT357;
DECLARE V_SUM_VAL_ABATIMENTOREPORTADO  ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_VENDASDIARIO.VAL_ABATIMENTOREPORTADO;
DECLARE V_SUM_VAL_ICMSZFMREPORTADO     ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_VENDASDIARIO.VAL_ICMSZFMREPORTADO;

DECLARE V_PROC                         ANCHOR DATA TYPE TO DMTLDBR.TB_TMP_LOG_EXECUTION_PROC.SYNCPOINT_PROC;
SET V_PROC = 'SP_DASH_CALENDARIO';

-- =========================================================================================================
--   P R O C   P R O C U R A _ D I A _ U T I L _ P O S T _ D I A 1
--
--  OBTEM O PRIMEIRO DIA ÚTIL DO MÊS (QUE NÃO SEJA DOMINGO NEM FERIADO)
--
-- =========================================================================================================
BEGIN
DECLARE PROCEDURE PROCURA_DIA_UTIL_POST_DIA1(IN P_ID_MES INTEGER)
BEGIN

        DECLARE V_ACHOU  DECIMAL(1) DEFAULT 0;
        DECLARE CONTINUE HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND BEGIN END;

        SET V_ID_DIA = NULL;

        L1: LOOP -- (LP01)

        BEGIN  -- (BE02.)

                DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' BEGIN END;

                SELECT MIN(ID_DIA) INTO V_ID_DIA
                FROM   DMTLDBR.TB_DIM_DIADIA
                WHERE  ID_MES     = P_ID_MES
                AND    ID_DIASEMANA  <> 1  -- DOMINGO
                AND    FLG_HOLIDAY = 0;

        END; -- (BE02.)

        IF SQLSTATE = '00000' THEN
                LEAVE L1;
         --SET V_ACHOU = 1;
        END IF;

        END LOOP L1; -- (LP01.)

END;
END;

CALL DMTLDBR.PROCURA_DIA_UTIL_POST_DIA1(201909);

END

【问题讨论】:

    标签: stored-procedures db2 call procedure declare


    【解决方案1】:

    Compound SQL (compiled) statement 要求内部声明/语句的严格顺序。
    例如:

    --#SET TERMINATOR @
    CREATE OR REPLACE PROCEDURE TEST_LOCAL(P_I INT)
    BEGIN
        -- SQL-variable-declarations
        DECLARE L_I INT;
    
        -- DECLARE-CURSOR-statements
        DECLARE C1 CURSOR FOR VALUES 1;
    
        -- procedure-declaration
        DECLARE PROCEDURE TEST_LOCAL_NESTED(P_J INT) BEGIN END;
    
        -- handler-declarations
        DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN END;
    
        -- SQL-procedure-statements
        CALL TEST_LOCAL_NESTED(P_I);
    END@
    

    简要介绍每个BEGIN END 块:

    1-st:所有SQL-variable-declarations
    第二名:全部DECLARE-CURSOR-statements
    第三名:全部procedure-declaration
    4-th:所有handler-declarations

    所有SQL-procedure-statements 仅在之后出现。这些语句可能包含嵌套的BEGIN END 块,其中适用相同的严格声明/语句规则。

    【讨论】:

      【解决方案2】:

      问题中显示的代码有不止一个错误。

      您正在使用本地过程,这是在另一个过程中声明的过程的名称。

      正确使用本地程序可以正常工作。

      一些成功编译的建议:

      • declare procedure 必须出现在调用过程中的任何可执行语句或新块之前。

        移动语句SET V_PROC = 'SP_DASH_CALENDARIO' 使其出现 在调用本地过程之前(或主过程块中的任何位置AFTER 所有声明(包括声明本地过程之后)。

        此外,删除DECLARE PROCEDURE 之前行上的 BEGIN(和匹配的 END)。 您希望 all 声明出现在 any 可执行语句或新的 begin-end 块之前。

      • 本地过程名称在 DECLARE 上 在 CALL 上必须是非限定的 但是您在 CALL 语句中使用了限定符,这将阻止 Db2 找到本地过程。

      您的程序的最后部分将如下所示:

      ...snip...
      
      DECLARE V_SUM_VAL_ICMSZFMREPORTADO     ANCHOR DATA TYPE TO DMTLDBR.TB_FATO_VENDASDIARIO.VAL_ICMSZFMREPORTADO;
      DECLARE V_PROC                         ANCHOR DATA TYPE TO DMTLDBR.TB_TMP_LOG_EXECUTION_PROC.SYNCPOINT_PROC;
      
      
          -- =========================================================================================================
          --   P R O C   P R O C U R A _ D I A _ U T I L _ P O S T _ D I A 1
          --
          --  OBTEM O PRIMEIRO DIA ÚTIL DO MÊS (QUE NÃO SEJA DOMINGO NEM FERIADO)
          --
          -- =========================================================================================================
          DECLARE PROCEDURE PROCURA_DIA_UTIL_POST_DIA1(IN P_ID_MES INTEGER)
          BEGIN
      
                  DECLARE V_ACHOU  DECIMAL(1) DEFAULT 0;
                  DECLARE CONTINUE HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND BEGIN END;
      
                  SET V_ID_DIA = NULL;
      
                  L1: LOOP -- (LP01)
      
                  BEGIN  -- (BE02.)
      
                          DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' BEGIN END;
      
                          SELECT MIN(ID_DIA) INTO V_ID_DIA
                          FROM   DMTLDBR.TB_DIM_DIADIA
                          WHERE  ID_MES     = P_ID_MES
                          AND    ID_DIASEMANA  <> 1  -- DOMINGO
                          AND    FLG_HOLIDAY = 0;
      
                  END; -- (BE02.)
      
                  IF SQLSTATE = '00000' THEN
                          LEAVE L1;
                   --SET V_ACHOU = 1;
                  END IF;
      
                  END LOOP L1; -- (LP01.)
      
          END;
      
          SET V_PROC = 'SP_DASH_CALENDARIO';
      
          CALL PROCURA_DIA_UTIL_POST_DIA1(201909);
      
          END@
      

      【讨论】:

        猜你喜欢
        • 2011-07-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-01
        • 2020-01-24
        相关资源
        最近更新 更多