Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a user defined function that returns a table in a DB2 module?

I am trying to create a user-defined function that returns a table in DB2. Here is what I have so far.

This is a table that I use:

CREATE TABLE "CORPDATA"."EMPLOYEE" (
    "EMPNO" CHAR(6) NOT NULL, 
    "FIRSTNME" VARCHAR(12) NOT NULL, 
    "MIDINIT" CHAR(1) NOT NULL, 
    "LASTNAME" VARCHAR(15) NOT NULL, 
    "WORKDEPT" CHAR(3), 
    "PHONENO" CHAR(4), 
    "HIREDATE" DATE, 
    "JOB" CHAR(8), 
    "EDLEVEL" SMALLINT NOT NULL, 
    "SEX" CHAR(1), 
    "BIRTHDATE" DATE, 
    "SALARY" DECIMAL(9 , 2), 
    "BONUS" DECIMAL(9 , 2), 
    "COMM" DECIMAL(9 , 2)
);

ALTER TABLE "CORPDATA"."EMPLOYEE" ADD CONSTRAINT "PK_EMPLOYEE" PRIMARY KEY
("EMPNO");

This is a user-defined function that returns a table (which is working fine):

CREATE OR REPLACE FUNCTION "CORPDATA"."DEPTEMPLOYEES" (DEPTNO CHAR(3))
 RETURNS TABLE (EMPNO CHAR(6),
                LASTNAME VARCHAR(15),
                FIRSTNAME VARCHAR(12))
 LANGUAGE SQL
 READS SQL DATA
 NO EXTERNAL ACTION
 DETERMINISTIC
 BEGIN ATOMIC
   RETURN
     SELECT EMPNO, LASTNAME, FIRSTNME
     FROM CORPDATA.EMPLOYEE
     WHERE WORKDEPT = "DEPTEMPLOYEES".DEPTNO;
 END

This is a how far I was able to get with the module:

CREATE MODULE CORPDATA.MODULE1

ALTER MODULE CORPDATA.MODULE1
PUBLISH FUNCTION DEPTEMPLOYEES2 (DEPTNO CHAR(3))
RETURNS TABLE (EMPNO CHAR(6),
                LASTNAME VARCHAR(15),
                FIRSTNAME VARCHAR(12))

Any attempts to actually add a function to a module failed with various errors. Here is my DB2 version information: Database server = DB2/LINUXX8664 11.1.2.2 This is an Express-C installation under Redhat.

When I try this, I get SQL0628N Multiple or conflicting keywords involving the "RETURNS" clause are present. LINE NUMBER=16. SQLSTATE=42613

ALTER MODULE corpdata.module1
ADD FUNCTION DEPTEMPLOYEES (DEPTNO CHAR(3))
     RETURNS TABLE (EMPNO CHAR(6),
                    LASTNAME VARCHAR(15),
                    FIRSTNAME VARCHAR(12))
     LANGUAGE SQL
     READS SQL DATA
     NO EXTERNAL ACTION
     DETERMINISTIC
BEGIN ATOMIC
     RETURN
       SELECT EMPNO, LASTNAME, FIRSTNME
       FROM CORPDATA.EMPLOYEE
       WHERE WORKDEPT = "DEPTEMPLOYEES".DEPTNO;
END

When I try this (removed RETURNS clause), I get SQL0491N The CREATE FUNCTION or ALTER MODULE statement used to define "CORPDATA.MODULE1.DEPTEMPLOYEES" must have a RETURNS clause, and one of: the EXTERNAL clause (with other required keywords); an SQL function body; or the SOURCE clause. LINE NUMBER=8. SQLSTATE=42601

ALTER MODULE corpdata.module1
ADD FUNCTION DEPTEMPLOYEES (DEPTNO CHAR(3))
     LANGUAGE SQL
     READS SQL DATA
     NO EXTERNAL ACTION
     DETERMINISTIC
BEGIN ATOMIC
     RETURN
       SELECT EMPNO, LASTNAME, FIRSTNME
       FROM CORPDATA.EMPLOYEE
       WHERE WORKDEPT = "DEPTEMPLOYEES".DEPTNO;
END

When I try this (removed BEGIN ATOMIC), I get SQL0104N An unexpected token "SELECT" was found following "INISTIC RETURN ". Expected tokens may include: "(". LINE NUMBER=9. SQLSTATE=42601 :) Yes, it does say "INISTIC".

ALTER MODULE corpdata.module1
ADD FUNCTION DEPTEMPLOYEES (DEPTNO CHAR(3))
 LANGUAGE SQL
 READS SQL DATA
 NO EXTERNAL ACTION
 DETERMINISTIC
 RETURN
   SELECT EMPNO, LASTNAME, FIRSTNME
   FROM CORPDATA.EMPLOYEE
   WHERE WORKDEPT = "DEPTEMPLOYEES".DEPTNO
like image 572
Andrey Belykh Avatar asked Aug 16 '17 18:08

Andrey Belykh


People also ask

How do you call a user-defined function in Db2?

Recommendations for invoking user-defined functions: The access path that Db2 chooses for a predicate determines whether a user-defined function in that predicate is invoked. To ensure that Db2 executes the external action for each row of the result table, put the user-defined function invocation in the SELECT list.

What is table function in Db2?

A table function can be used only in the FROM clause of a statement. Table functions return columns of a table and resemble a table created using a CREATE TABLE statement. Table functions can be qualified with a schema name.

How do you call a table function?

To invoke a user-defined table function, reference the function in the FROM clause of an SQL statement where it is to process a set of input values. The reference to the table function must be preceded by the TABLE clause and be contained in brackets.

Can we call a user-defined function in a SELECT statement?

For example, user-defined functions can be used in the following: The select list of a SELECT statement. The condition of a WHERE clause. CONNECT BY , START WITH , ORDER BY , and GROUP BY clauses.


1 Answers

It appears that DB2 LUW as at version 11.1 does not yet fully support table-functions inside modules unless that table-function includes the PIPE statement. This is despite the published documentation suggesting that it's possible with some restrictions. This is the reason you get the "conflicting keywords" error, since a pipelined function can only return one row at a time which is the opposite of RETURNS TABLE.

Check also if implementing a pipelined function might satisfy your requirements in this area.

When modules arrived at Db2 V9.7 they did not support table functions in modules at all, but since V10.1 there appeared to be some support for module table-functions, although the documentation was vague, lacking worked examples and the samples were not updated specifically for this.

There's a reference to this limitation on developerworks dating from 2014.

If this is important to your company, consider opening a request for enhancement (RFE), google for details.

You might also want to submit a documentation remark on the Db2 Knowledge Centre page for alter-module, and also on the restrictions-on-modules page, which do not mention the additional restriction on table-function inside modules regarding the use of the PIPE statement.

like image 86
mao Avatar answered Sep 18 '22 08:09

mao