【问题标题】:How to create a user defined function that returns a table in a DB2 module?如何创建返回 DB2 模块中的表的用户定义函数?
【发布时间】:2018-01-24 23:50:46
【问题描述】:

我正在尝试创建一个返回 DB2 中的表的用户定义函数。这是我目前所拥有的。

这是我使用的表格:

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");

这是一个用户定义的函数,它返回一个表(工作正常):

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

这是我使用该模块能走多远:

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))

任何向模块实际添加功能的尝试都因各种错误而失败。这是我的 DB2 版本信息: 数据库服务器 = DB2/LINUXX8664 11.1.2.2 这是 Redhat 下的 Express-C 安装。

当我尝试这个时,我得到 SQL0628N 涉及“RETURNS”子句的多个或冲突关键字是 展示。第 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

当我尝试这个(删除 RETURNS 子句)时,我得到 SQL0491N 用于定义的 CREATE FUNCTION 或 ALTER MODULE 语句 “CORPDATA.MODULE1.DEPTEMPLOYEES”必须有一个 RETURNS 子句,并且是以下之一: EXTERNAL 子句(带有其他必需的关键字); SQL 函数体;或者 源子句。第 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

当我尝试这个(删除 BEGIN ATOMIC)时,我得到 SQL0104N 在“INISTIC”之后发现了意外的标记“SELECT” RETURN "。预期的标记可能包括:"("。LINE NUMBER=9。SQLSTATE=42601 :) 是的,它确实说“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

【问题讨论】:

  • 您认为包含您遇到的“各种错误”是否有用,还是我们应该开始猜测?
  • 可能是this会给你一个提示:“当SQL-routine-body是复合SQL(编译)语句指定NOT ATOMIC时,模块函数定义只能指定RETURNS TABLE子句"。
  • 我会更新一些我尝试过的东西。
  • 好吧,你需要再次阅读手册中的语法图。由于不支持的内联复合 SQL (begin atomic),前两次尝试失败;最后一个失败,因为它缺少returns 子句。
  • 但是如果我添加 RETURNS 子句,它会给出 SQL0628N 存在多个涉及“RETURNS”子句的关键字或冲突关键字。行号=10。 SQLSTATE=42613,如 #1。所以,基本上,你是说,这是不可能的?

标签: module db2 user-defined-functions db2-luw


【解决方案1】:

似乎 DB2 LUW 版本 11.1 尚未完全支持模块内的表函数,除非该表函数包含 PIPE 语句。尽管已发布的文档表明它可能会受到一些限制。这就是您收到“关键字冲突”错误的原因,因为流水线函数一次只能返回一行,这与 RETURNS TABLE 相反。

还要检查实现流水线功能是否可以满足您在这方面的要求。

当模块到达 Db2 V9.7 时,它们根本不支持模块中的表函数,但从 V10.1 开始,似乎对模块表函数有一些支持,尽管文档含糊不清,缺乏工作示例和没有专门为此更新示例。

developerworks 的这一限制可追溯到 2014 年。

如果这对您的公司很重要,请考虑打开增强请求 (RFE),Google 了解详情。

您可能还想在 alter-module 的 Db2 知识中心页面和 restrictions-on-modules 页面上提交文档备注,其中没有提到关于使用管道声明。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-11
    相关资源
    最近更新 更多