Как я могу вызвать процедуру, объявленную внутри другой процедуры? - PullRequest
0 голосов
/ 04 октября 2019

У меня есть сомнения относительно процедур в 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; PROCEDURE, DRIVER = 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

Ответы [ 2 ]

1 голос
/ 05 октября 2019

A Составной SQL (скомпилированный) оператор требует строгого порядка объявлений / операторов внутри.
Например:

--#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-й: все SQL-variable-declarations
2-й: все DECLARE-CURSOR-statements
3-й: все procedure-declaration
4-й: все handler-declarations

Все SQL-procedure-statements приходят только после. Эти операторы могут содержать вложенные блоки BEGIN END, к которым применяются те же строгие правила объявления / оператора.

0 голосов
/ 05 октября 2019

В коде, показанном в вопросе, имеется более одной ошибки.

Вы используете локальную процедуру , то есть имя процедуры, объявленной внутри другой процедуры.

Локальные процедуры работают нормально при правильном использовании.

Некоторые предложения по успешной компиляции:

  • declare procedure должно появляться перед любыми исполняемыми операторами или новымиblock в вызывающей процедуре.

    Переместите оператор SET V_PROC = 'SP_DASH_CALENDARIO' так, чтобы он появлялся перед CALL в локальной процедуре (или в любом месте блока главной процедуры ПОСЛЕ всех объявлений (в том числе после объявления). локальная процедура).

    Кроме того, удалите BEGIN (и соответствующий END) в строке перед DECLARE PROCEDURE. Вы хотите, чтобы все объявления объявлялись до any исполняемый оператор или новый блок начала и конца.

  • имя локальной процедуры должно быть неквалифицированным и в DECLARE и в CALL but вы используете квалификатор в вашем операторе 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@
...