我对Db2中的程序有疑问。我使用“ CREATE PROCEDURE”创建了一个存储过程,并且在其中有另一个使用“ DECLARE PROCEDURE”声明的过程。但是,不能通过“ 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
A 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位:全部handler-declarations
所有SQL-procedure-statements
仅在之后出现。这些语句可能包含嵌套的BEGIN END
块,其中应用相同的严格声明/语句规则。
您在问题中显示的代码中有多个错误。
您正在使用本地过程,这是在另一个过程中声明的过程的名称。
正确使用本地程序可以正常工作。
一些建议,可以成功进行编译:
declare procedure
必须出现在调用过程中的任何可执行语句或新块之前。
移动语句SET V_PROC = 'SP_DASH_CALENDARIO'
使其显示在CALL之前到达本地过程(或主过程块AFTER中的任何位置)所有声明(包括声明本地过程之后的声明)。
另外,在DECLARE PROCEDURE
之前的行中删除BEGIN(和匹配的END)。您希望all声明出现在any可执行语句或新的begin-end块之前。
本地过程名称必须在CALL上的DECLARE 和上不合格both]但您在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@