Search code examples
db2db2-luwsql-pl

SQL0628N with MODIFIES SQL DATA when creating a table function


I am trying to encapsulate the functionality from this sample code here, inside a Table-Function.

I can run the sample alone without any problem.

But when I create a table function, just with a single call to OPEN_CURSOR , I receive 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

it seems, OPEN_CURSOR demands to have the MODIFY SQL DATA specified.. ok.. let's go! But, when I specify it, then I get the following error, instead:

SQL0628N  Multiple or conflicting keywords involving the "MODIFIES SQL DATA"
clause are present.  LINE NUMBER=33.  SQLSTATE=42613

The error details for -628 error is too generic and does not help me to determine what's really going on here.

I need to perform dynamic SQL queries using DBMS_SQL module, and return the result set using PIPE , like this other sample here.

I have been reading spread documentations the entire day.. and so far was not able to determine exactly what rule I am violating.

Also, found some inconsistencies on documentation, which I don't understand: This page, says:

  • SQL table functions cannot contain compiled compound statements.

While, the Rules from RETURN statement says the opposite, and matches with PIPE sample code:

  • In an SQL table function using a compound SQL (compiled) statement, an expression, NULL, or fullselectcannot be specified. Rows are returned from the function using the PIPE statement and the RETURN statement is required as the last statement to execute when the function exits (SQLSTATE 2F005).

Appreciate any help!


Solution

  • Look at the note about the MODIFIES SQL DATA in the CREATE FUNCTION statement description:

    4 Valid only for compiled scalar function definition and an inlined table function definition.

    But you can't use PIPE in an inlined function.
    So, you want to use different functionalities, which can't be used together.
    The inconsistency you found in the documentation is not related to you problem.