我有一些简单的函数可以在 DB2 中工作,但是我无法让任何声明全局临时表的函数起作用。我知道 DB2 版本和平台有很大不同,但我认为这应该是可能的,因为它适用于 这张海报。
CREATE FUNCTION FuncTest1 ()
RETURNS TABLE
(
USE_NAME VARCHAR(48),
USE_PARTNER_LINK FLOAT
)
LANGUAGE SQL
MODIFIES SQL DATA
DETERMINISTIC
BEGIN
DECLARE GLOBAL TEMPORARY TABLE USE_TRUNC
(
USE_NAME VARCHAR(48) NULL,
USE_PARTNER_LINK FLOAT NULL
);
INSERT INTO SESSION.USE_TRUNC
(USE_NAME,USE_PARTNER_LINK)
SELECT USE_NAME,USE_PARTNER_LINK FROM F_USERS;
RETURN
SELECT USE_NAME,USE_PARTNER_LINK FROM F_USERS;
END
当我尝试不同的事情时,错误差异很大,但这是当前的输出:
An unexpected token "USE_NAME" was found following "
RETURN
SELECT". Expected tokens may include: "(".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.9.78
添加了小提琴
CREATE FUNCTION(SQL 标量、表或行)语句,v9.7:
-| (3)| '-MODIFIES SQL DATA-----' ... |--+-RETURN----------------------+------------------------------| | (5) | +-Compound SQL (compiled)-----+ '-Compound SQL (inlined)------'
...
3. 如果 RETURNS 指定表(即 TABLE 列列表),则有效。如果 RETURNS 指定标量结果并且 SQL-function-body 是一个复合 SQL(编译)语句。
...
5. 仅 SQL 标量函数定义中的 SQL 函数体支持复合 SQL(已编译)语句。 不是 支持 SQL 表函数定义。
CREATE FUNCTION(SQL 标量、表或行)语句,v11.1:
-| (4) | '-MODIFIES SQL DATA-----'
...
4. 仅对已编译的标量函数定义和内联表函数定义有效。
您不能将
MODIFIED SQL DATA
与 Compound SQL (compiled)
(BEGIN ... END
) 用于表函数。并且DECLARE GTT
的说法不受Compound SQL (inlined)
(BEGIN ATOMIC ... END
)的支持。您可以使用单个
SELECT
语句与 Common Table Expression
:
CREATE FUNCTION ...
...
RETURN
WITH
SESSION_ALLREFERRALS AS
(
SELECT
REF.AL_NO AS AL_NO,
ENQ.E_KEY AS R_KEY,
APP.A_2ND_NAME AS R_TRADING_NAME,
CASE WHEN DOC1.DT_NAME is null THEN 'NONE' ELSE DOC1.DT_NAME END AS R_DROP1,
REF.AL_DATE AS R_DATE,
CASE WHEN DOC2.DT_NAME is null THEN 'Incomplete' ELSE DOC2.DT_NAME END AS R_DROP2,
CAST(ENQ2.E_TOOLCOMM1 AS VARCHAR(48)) AS R_COMM1
FROM
F_ENQUIRY ENQ INNER JOIN
F_APPLICANT_LINK REF ON REF.AL_KEY1 = ENQ.E_KEY INNER JOIN
F_APPLICANT APP ON APP.A_KEY = REF.AL_KEY2 AND REF.AL_TYPE1 = 2 AND REF.AL_TYPE2 = 1 LEFT JOIN
F_DOC_TYPES DOC1 ON DOC1.DT_NO = REF.AL_DROP1 LEFT JOIN
F_DOC_TYPES DOC2 ON DOC2.DT_NO = REF.AL_DROP2 INNER JOIN
F_ENQUIRY ENQ2 ON ENQ2.E_KEY = REF.AL_ENQ_LINK
WHERE
ENQ.E_PRIORITY_LINK = 204 AND
ENQ.E_JOB_TYPE_LINK = 0
)
,
SESSION_REFERRAL1 AS
(
SELECT
MIN(AL_NO) AL_NO,
R_KEY
FROM
SESSION_ALLREFERRALS
GROUP BY R_KEY
)
,
SESSION_REFERRAL2 AS
(
SELECT
MIN(AL_NO) AL_NO,
R_KEY
FROM
SESSION_ALLREFERRALS a2
WHERE
NOT EXISTS (SELECT 1 FROM SESSION_REFERRAL1 R1 WHERE r1.AL_NO = a2.AL_NO fetch first 1 rows only)
GROUP BY
R_KEY
)
,
SESSION_REFERRAL3 AS
(
SELECT
MIN(AL_NO) AL_NO,
R_KEY
FROM
SESSION_ALLREFERRALS A3
WHERE
NOT EXISTS (SELECT 1 FROM SESSION_REFERRAL1 R1 WHERE R1.AL_NO = A3.AL_NO fetch first 1 rows only) AND
NOT EXISTS (SELECT 1 FROM SESSION_REFERRAL2 R2 WHERE R2.AL_NO = A3.AL_NO fetch first 1 rows only)
GROUP BY
R_KEY
)
SELECT
*
FROM
SESSION_REFERRAL1 R1 INNER JOIN
SESSION_ALLREFERRALS A ON A.R_KEY = R1.R_KEY AND R1.AL_NO = A.AL_NO LEFT JOIN
SESSION_REFERRAL2 R2 ON R2.R_KEY = R1.R_KEY LEFT JOIN
SESSION_ALLREFERRALS A2 ON A2.R_KEY = R2.R_KEY AND R2.AL_NO = A2.AL_NO LEFT JOIN
SESSION_REFERRAL3 R3 ON R3.R_KEY = R1.R_KEY LEFT JOIN
SESSION_ALLREFERRALS A3 ON A3.R_KEY = R3.R_KEY AND R3.AL_NO = A3.AL_NO
;
这将是编写该函数的更简单的方法
CREATE FUNCTION FuncTest1 ()
RETURNS TABLE
(
USE_NAME VARCHAR(48),
USE_PARTNER_LINK FLOAT
)
LANGUAGE SQL
RETURN SELECT USE_NAME,USE_PARTNER_LINK FROM F_USERS;
我知道这是一个已经在一定程度上回答的老问题,但我正在为OP留下的未决问题添加进一步的答案。
我不确定系统环境。但是 DB2 需要在创建 TEMPORARY 表之前定义用户可用的“USER TEMPORARY TABLESPACE”。 “LIST TABLESPACES”应该为您提供可用表空间的列表,并且其中至少一个应该是用于用户临时数据的“系统管理空间”。 如果这样的表空间不存在,管理员可以创建一个,这样就可以解决无法创建全局临时表的问题。