如何从PL / pgSQL函数返回行构造函数?

时间:2018-05-31 14:53:07

标签: sql postgresql plpgsql

我正在尝试从PL / pgSQL函数返回行构造函数,但它失败并出现以下错误:返回的类型记录与第1列中的预期类型整数不匹配

这是一个带有普通SQL函数的简化版本作为比较。 SQL函数运行正常,PL / pgSQL函数抛出以下错误。我在这里缺少什么?

测试功能

CREATE FUNCTION test_sql()
RETURNS TABLE (
    a int,
    b int
)
LANGUAGE SQL
IMMUTABLE
AS $$
    SELECT (1, 1);
$$;

CREATE FUNCTION test_plpgsql()
RETURNS TABLE (
    a int,
    b int
)
LANGUAGE plpgsql
IMMUTABLE
AS $$
BEGIN
    RETURN QUERY SELECT (1, 1);
END;
$$;

SELECT * FROM test_sql();     -- OK
SELECT * FROM test_plpgsql(); --error

错误消息

[42804] ERROR: structure of query does not match function result type
Detail: Returned type record does not match expected type integer in column 1.
Where: PL/pgSQL function test_plpgsql() line 3 at RETURN QUERY

3 个答案:

答案 0 :(得分:1)

RETURN QUERY中使用常规查询(返回列,而不是元组):

CREATE OR REPLACE FUNCTION test_plpgsql()
RETURNS TABLE (
    a int,
    b int
)
LANGUAGE plpgsql
IMMUTABLE
AS $$
BEGIN
    RETURN QUERY SELECT 1, 1;
END;
$$;

答案 1 :(得分:1)

实际上这两个功能都是不正确的。 SELECT (1, 1)选择一行记录的一行,而不是两列类型为整数的列。

由于某种原因,这可以在SQL函数中隐式转换。但是在两个函数中将其更改为SELECT 1, 1将为您提供所需的内容。

答案 2 :(得分:0)

我在设计中看到两个问题:

  1. 是SRF(设置返回功能),在这种情况下没用。
  2. 您使用SELECT作为常量,它也没用 - 而且速度较慢:
  3. postgres=# CREATE OR REPLACE FUNCTION test_plpgsql(OUT a int, OUT b int)
    AS $$
    BEGIN
      a := 1; b := 1;
    END;
    $$ LANGUAGE plpgsql IMMUTABLE;
    CREATE FUNCTION
    
    postgres=# SELECT * FROM test_plpgsql();
    ┌───┬───┐
    │ a │ b │
    ╞═══╪═══╡
    │ 1 │ 1 │
    └───┴───┘
    (1 row)