0

我正在尝试将这里示例代码中的功能封装在一个表函数中。

我可以单独运行示例而没有任何问题。

但是当我创建一个表函数时,只需一次调用 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)。

感谢任何帮助!

4

1 回答 1

2

查看关于CREATE FUNCTION语句描述MODIFIES SQL DATA中的注释:

4 仅对编译的标量函数定义和内联表函数定义有效。

但是你不能PIPE在内联函数中使用。
因此,您想使用不能一起使用的不同功能。
您在文档中发现的不一致与您的问题无关。

于 2021-11-25T21:07:14.720 回答