为什么在此 DB2 函数中使用 IF-ENDIF 块会导致
Why does using the IF-ENDIF block in this DB2 function cause
为什么在此函数中使用IF语句会导致错误42601 [SQL0104],如下所示..?这是 DB2-400 for i v7r3m0。
SQL Error [42601]: [SQL0104] Token <END-OF-STATEMENT> was not valid. Valid tokens: ;.
我在下面提供的代码示例在 IF 语句取消注释之前执行时没有错误。我试过移动分号甚至删除它们,但随后错误变得更糟并开始指向后面的语句无效。
我已经检查过 IBM documentation for IF on v7r3, and my syntax seems to be correct. Other code examples 是否遵循与我相同的语法。我被难住了。
CREATE OR REPLACE FUNCTION F_CERT.CERT_UPC_COMMON_DESC (UPC NUMERIC(14))
RETURNS INTEGER
LANGUAGE SQL
GLOBAL DETERMINISTIC
NO EXTERNAL ACTION
NOT FENCED
ALLOW PARALLEL
BEGIN
DECLARE RETVAL INTEGER DEFAULT 0 ;
DECLARE UPC_COUNT INTEGER DEFAULT 0 ;
DECLARE UPC_LIST CURSOR FOR
SELECT COUNT(*)
FROM F_CERTOB.BEERXT
WHERE BXUPCR=UPC
;
OPEN UPC_LIST ;
FETCH UPC_LIST INTO UPC_COUNT ;
CLOSE UPC_LIST ;
-- IF UPC_COUNT > 0 THEN
-- -- OTHER
-- -- COMMANDS
SET RETVAL = UPC_COUNT ;
-- END IF ;
RETURN RETVAL ;
END ;
SELECT F_CERT.CERT_UPC_COMMON_DESC (793936791660) AS C FROM SYSIBM.SYSDUMMY1 ;
编辑:
这是第二个例子;精简版与上面的代码一样,一切都很好,直到 IF 语句被取消注释:
CREATE OR REPLACE FUNCTION F_CERT.CERT_UPC_COMMON_DESC (UPC NUMERIC(14))
RETURNS INTEGER
LANGUAGE SQL
BEGIN
DECLARE RETVAL INTEGER DEFAULT 0 ;
-- IF 1=1 THEN
SET RETVAL = 1 ;
-- ELSE
SET RETVAL = 100 ;
-- END IF ;
RETURN RETVAL ;
END ;
SELECT F_CERT.CERT_UPC_COMMON_DESC (12345) AS C FROM SYSIBM.SYSDUMMY1 ;
自从我的 OP 以来我一直在搜索,我终于找到了确切的解决方案
here.
问题是语句分隔符。当函数包含跨多行的流程控制和类似结构的语句时,就会出现冲突。在我的代码示例中,编译器在 END IF;
处停止并认为这就是全部,而不是继续到函数的 END;
。
我的 SQL 客户端是 DBeaver 5.2.5,它确实具有一些以不同方式 运行 语句和脚本的功能。 This article 给了我尝试 运行 将我的 CREATE
脚本与 DBeaver 的不同操作结合起来的想法,我发现如果我突出显示 [=13= 中的整个脚本,我可以让它工作] 到 END
但不包括尾随分号 。然后我使用 Execute Statement {Ctrl+Enter}
而不是通常的 Execute Sctipt {Alt+X}
。它终于奏效了..!!但这似乎 "kludgy" 所以我继续寻找解决方案。
然后我在上面提到的main article中找到了不完美但完全可以接受的解决方案。我按照说明更改我的 DBeaver 客户端中的设置,并如下所示编辑我的代码(注意 @
字符)。然后它终于奏效了..!!我可以 运行 整个脚本,包括 SELECT
语句,并且能够使用我已经习惯的常用 Execute Statement {Alt+X}
击键来完成。
CREATE OR REPLACE FUNCTION F_CERT.CERT_UPC_COMMON_DESC (UPC NUMERIC(14))
RETURNS INTEGER
LANGUAGE SQL
BEGIN
DECLARE RETVAL INTEGER DEFAULT 0;
IF 1=0 THEN
SET RETVAL = 1;
ELSE
SET RETVAL = 100;
END IF;
RETURN RETVAL;
END @
SELECT F_CERT.CERT_UPC_COMMON_DESC (793936791660) AS C FROM SYSIBM.SYSDUMMY1 @
为什么在此函数中使用IF语句会导致错误42601 [SQL0104],如下所示..?这是 DB2-400 for i v7r3m0。
SQL Error [42601]: [SQL0104] Token <END-OF-STATEMENT> was not valid. Valid tokens: ;.
我在下面提供的代码示例在 IF 语句取消注释之前执行时没有错误。我试过移动分号甚至删除它们,但随后错误变得更糟并开始指向后面的语句无效。
我已经检查过 IBM documentation for IF on v7r3, and my syntax seems to be correct. Other code examples 是否遵循与我相同的语法。我被难住了。
CREATE OR REPLACE FUNCTION F_CERT.CERT_UPC_COMMON_DESC (UPC NUMERIC(14))
RETURNS INTEGER
LANGUAGE SQL
GLOBAL DETERMINISTIC
NO EXTERNAL ACTION
NOT FENCED
ALLOW PARALLEL
BEGIN
DECLARE RETVAL INTEGER DEFAULT 0 ;
DECLARE UPC_COUNT INTEGER DEFAULT 0 ;
DECLARE UPC_LIST CURSOR FOR
SELECT COUNT(*)
FROM F_CERTOB.BEERXT
WHERE BXUPCR=UPC
;
OPEN UPC_LIST ;
FETCH UPC_LIST INTO UPC_COUNT ;
CLOSE UPC_LIST ;
-- IF UPC_COUNT > 0 THEN
-- -- OTHER
-- -- COMMANDS
SET RETVAL = UPC_COUNT ;
-- END IF ;
RETURN RETVAL ;
END ;
SELECT F_CERT.CERT_UPC_COMMON_DESC (793936791660) AS C FROM SYSIBM.SYSDUMMY1 ;
编辑:
这是第二个例子;精简版与上面的代码一样,一切都很好,直到 IF 语句被取消注释:
CREATE OR REPLACE FUNCTION F_CERT.CERT_UPC_COMMON_DESC (UPC NUMERIC(14))
RETURNS INTEGER
LANGUAGE SQL
BEGIN
DECLARE RETVAL INTEGER DEFAULT 0 ;
-- IF 1=1 THEN
SET RETVAL = 1 ;
-- ELSE
SET RETVAL = 100 ;
-- END IF ;
RETURN RETVAL ;
END ;
SELECT F_CERT.CERT_UPC_COMMON_DESC (12345) AS C FROM SYSIBM.SYSDUMMY1 ;
自从我的 OP 以来我一直在搜索,我终于找到了确切的解决方案 here.
问题是语句分隔符。当函数包含跨多行的流程控制和类似结构的语句时,就会出现冲突。在我的代码示例中,编译器在 END IF;
处停止并认为这就是全部,而不是继续到函数的 END;
。
我的 SQL 客户端是 DBeaver 5.2.5,它确实具有一些以不同方式 运行 语句和脚本的功能。 This article 给了我尝试 运行 将我的 CREATE
脚本与 DBeaver 的不同操作结合起来的想法,我发现如果我突出显示 [=13= 中的整个脚本,我可以让它工作] 到 END
但不包括尾随分号 。然后我使用 Execute Statement {Ctrl+Enter}
而不是通常的 Execute Sctipt {Alt+X}
。它终于奏效了..!!但这似乎 "kludgy" 所以我继续寻找解决方案。
然后我在上面提到的main article中找到了不完美但完全可以接受的解决方案。我按照说明更改我的 DBeaver 客户端中的设置,并如下所示编辑我的代码(注意 @
字符)。然后它终于奏效了..!!我可以 运行 整个脚本,包括 SELECT
语句,并且能够使用我已经习惯的常用 Execute Statement {Alt+X}
击键来完成。
CREATE OR REPLACE FUNCTION F_CERT.CERT_UPC_COMMON_DESC (UPC NUMERIC(14))
RETURNS INTEGER
LANGUAGE SQL
BEGIN
DECLARE RETVAL INTEGER DEFAULT 0;
IF 1=0 THEN
SET RETVAL = 1;
ELSE
SET RETVAL = 100;
END IF;
RETURN RETVAL;
END @
SELECT F_CERT.CERT_UPC_COMMON_DESC (793936791660) AS C FROM SYSIBM.SYSDUMMY1 @