我正在尝试将这里示例代码中的功能封装在一个表函数中。
我可以单独运行示例而没有任何问题。
但是当我创建一个表函数时,只需一次调用 OPEN_CURSOR ,我就会收到SQL0577N
CREATE FUNCTION ROW_CHECKSUM
( IN sSchema VARCHAR(128) ,
IN sTable VARCHAR(128) ,
IN sColumnList VARCHAR(1024) ,
IN sWhere VARCHAR(1023),
IN iRows INTEGER
)
RETURNS TABLE (ROW_PK_VALUES VARCHAR(3000), CHECKSUM INTEGER )
LANGUAGE SQL
SPECIFIC ROW_CHECKSUM
--NO EXTERNAL ACTION
--MODIFIES SQL DATA
--NOT DETERMINISTIC
BEGIN
DECLARE iCheckSum INTEGER ;
DECLARE sKyes VARCHAR(1024) ;
DECLARE iCursor INTEGER;
DECLARE sQuery VARCHAR(32000) ;
SET sQuery = 'SELECT ' || sColumnList || ' FROM "' || sSchema || '"."' || sTable || '" WHERE ' || sWhere || ' FETCH FIRST ' || TO_CHAR(iRows) || ' ONLY' ;
CALL DBMS_SQL.OPEN_CURSOR(iCursor);
--CALL DBMS_SQL.PARSE(iCursor, sQuery, DBMS_SQL.native) ;
--PIPE (sKeys, iCheckSum) ;
--PIPE ('abcd', 1234) ;
RETURN ;
END
----
SQL0577N User defined routine "DB2ADMIN.ROW_CHECKSUM" (specific name "")
attempted to modify data but was not defined as MODIFIES SQL DATA. LINE
NUMBER=33. SQLSTATE=38002
看来,OPEN_CURSOR 要求指定 MODIFY SQL DATA.. 好的.. 走吧!但是,当我指定它时,我会收到以下错误:
SQL0628N Multiple or conflicting keywords involving the "MODIFIES SQL DATA"
clause are present. LINE NUMBER=33. SQLSTATE=42613
-628 错误的错误详细信息过于笼统,无法帮助我确定这里到底发生了什么。
我需要使用 DBMS_SQL 模块执行动态 SQL 查询,并使用 PIPE 返回结果集,就像这里的其他示例一样。
我一整天都在阅读传播文件。到目前为止,我无法确定我到底违反了什么规则。
另外,在文档上发现了一些我不明白的不一致之处:此页面说:
- SQL 表函数不能包含已编译的复合语句。
而来自RETURN 语句的规则则相反,并与 PIPE 示例代码匹配:
- 在使用复合 SQL(编译)语句的 SQL 表函数中,不能指定表达式、NULL 或全查询。使用 PIPE 语句从函数返回行,并且需要 RETURN 语句作为函数退出时执行的最后一条语句 (SQLSTATE 2F005)。
感谢任何帮助!