【问题标题】:Use of custom return types in a FOR loop in plpgsql在 plpgsql 的 FOR 循环中使用自定义返回类型
【发布时间】:2015-03-10 03:26:28
【问题描述】:

我使用的以下代码返回一个整数1

CREATE TYPE my_test AS (
   foo Integer
  );

CREATE FUNCTION foo_out() 
  RETURNS SETOF Integer AS
$$ 
BEGIN
RETURN QUERY
SELECT 1 as foo;
END
$$
LANGUAGE plpgsql;

CREATE FUNCTION foo1()
  RETURNS SETOF my_test
AS $$
DECLARE
    x my_test;
BEGIN
    FOR x IN    
        SELECT foo_out()
    LOOP     
        RETURN NEXT x;
    END LOOP;
END;
$$
LANGUAGE 'plpgsql';

select * from foo1();

但是为什么返回相同的代码:

ERROR:  invalid input syntax for integer: (1)

如果我将返回类型更改为:

CREATE FUNCTION foo_out() 
  RETURNS SETOF my_test 

也应该是integer!?可能是系统在整数类型和包含整数的自定义类型之间存在差异。在这里可以使用自定义类型应该改变什么?

【问题讨论】:

  • 你可以在第二个函数中使用select * from foo_out()

标签: postgresql for-loop types row plpgsql


【解决方案1】:

my_test 是一种复合类型,一种行类型,包含单个整数字段。 不是integer

当分配给FOR loop 中的记录或行类型时,查询形成行的所有输出列。您的 SELECT 需要返回一个未嵌套的 integer 列,然后将其嵌套到与您的自定义类型 my_test 匹配的行类型中。
您还可以在FOR 循环中分配给标量变量列表,在这种情况下,查询中的列从左到右分配给变量按原样 - 不形成一行。

如果列本身一种行类型,则您有一层嵌套到多层。包含整数字段的行的文本表示为“(1)”(带括号!),这就是您在错误消息中看到的内容。

你可以通过extracting the integer field from the row with attribute notation解决这个问题:

SELECT (foo_out()).*

或者(对于多列更有效)通过分解:

SELECT * FROM foo_out()

示例代码

CREATE FUNCTION foo_out() 
  RETURNS SETOF my_test
  LANGUAGE sql AS
'SELECT ''(1)''::my_test';

CREATE FUNCTION foo1()
  RETURNS SETOF my_test
  LANGUAGE plpgsql AS
$func$
DECLARE
   x my_test;
BEGIN
   FOR x IN    
      SELECT * FROM foo_out()
   LOOP     
      RETURN NEXT x;
   END LOOP;
END
$func$;

db小提琴here
sqlfiddle

不要引用语言名称plpgsql。这是一个标识符。

请记住,循环很少需要,因为使用基于集合的方法(仅限 SQL)可以更有效地解决大多数问题。

Craig 和 Pavel 的相关回答:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-27
    • 1970-01-01
    • 2016-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多