访问Postgres函数中的返回表

时间:2015-12-14 13:41:14

标签: sql-server postgresql function plpgsql

在MSSQL中,当在多语句表值函数内部时,您可以与表进行交互,如下所示。

CREATE FUNCTION dbo.test_func() RETURNS @table TABLE(id INT) AS
BEGIN
    INSERT INTO @table(id)
    SELECT 1 UNION SELECT 2 UNION SELECT 3

    UPDATE @table SET id = -1 WHERE id = 3
    RETURN
END
GO

有没有办法在Postgres 9.5中实现这一目标?我不确定要更新的内容如下所示。

CREATE FUNCTION test_func() RETURNS TABLE(id int) AS $$
BEGIN
    return QUERY SELECT 1 UNION SELECT 2 UNION SELECT 3;
    UPDATE ???? SET id = -1 WHERE id = 3;
END;
$$ LANGUAGE plpgsql STABLE;

2 个答案:

答案 0 :(得分:2)

使用RETURN NEXT or RETURN QUERY发送后,您无法更改功能结果集。

但是在PostgreSQL中,你不会被迫在一个语句中发送整个结果集(这就是为什么,你在PostgreSQL中提出的问题没有意义)。您可以使用RETURN NEXT逐行向结果集发送行,您可以使用RETURN QUERY / RETURN QUERY EXECUTE发送结果集的块,或者您甚至可以将其混合使用。 (您也可以使用没有参数的单个RETURN退出该功能。)

所以,你想做的事情可能是:

CREATE FUNCTION test_func() RETURNS TABLE(id int) AS $$
BEGIN
    RETURN QUERY VALUES (1), (2);
    -- do some calculation
    RETURN NEXT -1;
END;
$$ LANGUAGE plpgsql STABLE;

如果你真的想模仿what MSSQL does,你可以使用临时表,或者(最好)在函数内部选择​​:

CREATE FUNCTION test_func() RETURNS TABLE(id int) AS $$
BEGIN
    RETURN QUERY SELECT (SELECT CASE WHEN v = 3 THEN -1 ELSE v END res)
                 FROM   (VALUES (1), (2), (3)) v;
END;
$$ LANGUAGE plpgsql STABLE;

答案 1 :(得分:2)

CREATE FUNCTION test_func()
  RETURNS TABLE(id int) AS
$func$
BEGIN
   RETURN QUERY
   SELECT CASE WHEN v = 3 THEN -1 ELSE v END
   FROM   (VALUES (1), (2), (3)) v;
END
$func$ LANGUAGE plpgsql IMMUTABLE;

根本不需要PL / pgSQL。一个简单的SQL函数可以:

CREATE FUNCTION test_func()
  RETURNS SETOF int AS
$func$
   SELECT CASE WHEN v = 3 THEN -1 ELSE v END
   FROM   (VALUES (1), (2), (3)) v;
$func$ LANGUAGE sql IMMUTABLE;

对于简单案例,还演示了简单形式SETOF int而不是TABLE(id int)。你可以使用。

相关答案(许多其他人):

对于更复杂的操作,您可以使用CTE

CREATE FUNCTION test_func()
  RETURNS SETOF int AS
$func$
   WITH v(id) AS (VALUES (1), (2), (3))
   SELECT CASE WHEN id = 3 THEN -1 ELSE id END
   FROM   v
$func$ LANGUAGE sql IMMUTABLE;

对于更复杂的工作,您可以使用实际的temporary table