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,我试过了,但我在数据工作室中遇到了这个错误: 应该形成一个完整的范围。【参考方案3】:

我会像这样编写你的 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 语句的主要内容,如果未能解决你的问题,请参考以下文章

SQL入门经典 之自定义函数

SQL入门经典之自定义函数

方法 my_udf 有返回语句;需要结果类型

在 SQL SELECT 语句中未找到 UDF

如何从 UDF 参数提供 SELECT 语句的 FROM 子句

具有动态 SQL 语句的 Redshift UDF 函数