UDF 返回不同的 SQL 语句
Posted
技术标签:
【中文标题】UDF 返回不同的 SQL 语句【英文标题】:UDF Returning Different SQL statements 【发布时间】:2018-05-30 00:17:57 【问题描述】:我试图根据 IF 条件在 UDF 中返回两个不同的 SQL 语句。到目前为止,我还不能正确地做到这一点,下面的代码不起作用。我该怎么做?
CREATE FUNCTION BELSIZE.TEST (aSTRING VARCHAR(50))
RETURNS TABLE(
column1 INTEGER
, column2 INTEGER
, column3 VARCHAR(50)
)
------------------------------------------------------------------------
F1: BEGIN ATOMIC
DECLARE v_string VARCHAR(50);
SET v_string = aSTRING;
IF v_string = '123' THEN
With v (column1, column2, column3) as (
VALUES (1, 10231011, 'PRINCIPAL')
, (1, 10231012, 'ADDITIONAL')
, (-1, 10231031, 'REDEEM')
) select * from v;
END IF;
RETURN
With v (column1, column2, column3) as (
VALUES (1, 10231011, 'PRINCIPAL 456')
, (1, 10231012, 'ADDITIONAL 456')
, (-1, 10231031, 'REDEEM 456')
) select * from v;
END
谢谢。
【问题讨论】:
【参考方案1】:由于您需要基于输入字符串的 2 个不同的结果,因此您的返回语句应该在 IF-ELSE
逻辑上。您处理它的方式在您的查询中是错误的。它总是试图在返回块中返回一个。
我已更正符合您要求的查询。使用 IF-ELSE
逻辑。写在SQL-SERVER
CREATE FUNCTION dbo.testFn(@aSTRING VARCHAR(50))
RETURNS @rtnTable TABLE(
column1 INTEGER
, column2 INTEGER
, column3 VARCHAR(50)
)
AS
BEGIN
IF @aSTRING = '123'
BEGIN
INSERT INTO @rtnTable
VALUES (1, 10231011, 'PRINCIPAL')
, (1, 10231012, 'ADDITIONAL')
, (-1, 10231031, 'REDEEM')
END
ELSE
BEGIN
INSERT INTO @rtnTable
VALUES (1, 10231011, 'PRINCIPAL 456')
, (1, 10231012, 'ADDITIONAL 456')
, (-1, 10231031, 'REDEEM 456')
END
RETURN
END
【讨论】:
我曾尝试这样做,但使用 Data Studio for DB2 无法做到这一点。见下文。 我曾尝试这样做,但使用 Data Studio for DB2 无法做到这一点。见下文。CREATE FUNCTION BELSIZE.TEST (.... IF v_string = '123' THEN RETURN With v...; ELSE RETURN With v....; END IF; END
我收到以下错误:BELSIZE.TEST: 15: 具有特定名称 "" 的例程 "BELSIZE.TEST" 必须将 RETURN 语句作为复合体的最后一个 SQL 语句.. SQLCODE=-20148, SQLSTATE=429DB , 驱动=3.61.65
我认为你不应该 RETURN
任何来自你的 IF-ELSE
块。 1.在IF-ELSE
块之前创建一个临时表。 2. 使用IF-ELSE
块将数据插入临时表。 3. IF-ELSE
块之后的临时表中的单个 RETURN
语句。
你能给我一份临时表的样本吗?我之前没有在 UDF 中创建临时表。谢谢。
你可以看看here【参考方案2】:
您应该指定您的平台和 Db2 版本...
但是,我不相信这会有所作为。
Db2 从用户定义的表函数 (UDTF) 或存储过程返回行的方式是以定义在打开的函数/过程中的游标结束。
所以你需要这样的东西......
CREATE FUNCTION BELSIZE.TEST (aSTRING VARCHAR(50))
RETURNS TABLE(
column1 INTEGER
, column2 INTEGER
, column3 VARCHAR(50)
)
begin atomic
declare C1 cursor with return to client for
With v (column1, column2, column3) as (
VALUES (1, 10231011, 'PRINCIPAL')
, (1, 10231012, 'ADDITIONAL')
, (-1, 10231031, 'REDEEM')
) select * from v;
declare C2 cursor with return to client for
With v (column1, column2, column3) as (
VALUES (1, 10231011, 'PRINCIPAL 456')
, (1, 10231012, 'ADDITIONAL 456')
, (-1, 10231031, 'REDEEM 456')
) select * from v;
IF v_string = '123' THEN
open C1;
else
open C2;
END IF;
RETURN
END
【讨论】:
嗨,Charles,我试过了,但我在数据工作室中遇到了这个错误:我会像这样编写你的 UDF
CREATE FUNCTION BELSIZE.TEST (aSTRING VARCHAR(50))
RETURNS TABLE(
column1 INTEGER
, column2 INTEGER
, column3 VARCHAR(50)
)
RETURN
SELECT column1, column2, column3 FROM TABLE(
VALUES (0, 1, 10231011, 'PRINCIPAL')
, (0, 1, 10231012, 'ADDITIONAL')
, (0,-1, 10231031, 'REDEEM')
, (1, 1, 10231011, 'PRINCIPAL 456')
, (1, 1, 10231012, 'ADDITIONAL 456')
, (1,-1, 10231031, 'REDEEM 456')
) AS v(i, column1, column2, column3)
WHERE i = CASE WHEN aSTRING = '123' THEN 0 ELSE 1 END
【讨论】:
以上是关于UDF 返回不同的 SQL 语句的主要内容,如果未能解决你的问题,请参考以下文章