如何调用在另一个过程中声明的过程?
How can I call a procedure declared inside another procedure?
我对 Db2 中的过程有疑问。我使用 "CREATE PROCEDURE" 创建了一个存储过程,在其中我有另一个使用 "DECLARE PROCEDURE" 声明的存储过程。但是,这个由 declare 创建的过程不能使用 "CALL".
调用
当我尝试 运行 程序时,Db2 returns:
[Code: -440, SQL State: 42884] DB2 SQL Error: 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
问题中显示的代码中存在不止一个错误。
您正在使用 本地过程,这是在另一个过程中声明的过程的名称。
本地程序在正确使用时工作正常。
编译成功的一些建议:
declare procedure
必须出现在调用过程中任何可执行语句或新块之前。
移动语句 SET V_PROC = 'SP_DASH_CALENDARIO'
使其出现
在调用本地过程之前(或主过程块内的任何地方 AFTER
所有声明(包括声明本地过程之后)。
此外,删除 DECLARE PROCEDURE
之前行中的 BEGIN(和匹配的 END)。
您希望 all 声明出现在 any 可执行语句或新的 begin-end 块之前。
本地过程名称必须是非限定的 both DECLARE and 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@
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
块,其中适用相同的严格声明/语句规则。
我对 Db2 中的过程有疑问。我使用 "CREATE PROCEDURE" 创建了一个存储过程,在其中我有另一个使用 "DECLARE PROCEDURE" 声明的存储过程。但是,这个由 declare 创建的过程不能使用 "CALL".
调用当我尝试 运行 程序时,Db2 returns:
[Code: -440, SQL State: 42884] DB2 SQL Error: 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
问题中显示的代码中存在不止一个错误。
您正在使用 本地过程,这是在另一个过程中声明的过程的名称。
本地程序在正确使用时工作正常。
编译成功的一些建议:
declare procedure
必须出现在调用过程中任何可执行语句或新块之前。移动语句
SET V_PROC = 'SP_DASH_CALENDARIO'
使其出现 在调用本地过程之前(或主过程块内的任何地方 AFTER 所有声明(包括声明本地过程之后)。此外,删除
DECLARE PROCEDURE
之前行中的 BEGIN(和匹配的 END)。 您希望 all 声明出现在 any 可执行语句或新的 begin-end 块之前。本地过程名称必须是非限定的 both DECLARE and 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@
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
块,其中适用相同的严格声明/语句规则。