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

时间:2013-06-21 21:01:48

标签: postgresql plpgsql

我花了很多时间试图解决它,但我无法解决它。所以,我需要你的帮助。

我正在尝试编写一个返回多行的PL / pgSQL函数。我写的函数如下所示。但它没有用。

CREATE OR REPLACE FUNCTION get_object_fields()
RETURNS SETOF RECORD
AS 
$$
DECLARE result_record keyMetrics;
BEGIN
    return QUERY SELECT department_id into result_record.visits 
    from fact_department_daily 
    where report_date='2013-06-07';
    --return result_record;
END

$$ LANGUAGE plpgsql; 

SELECT * FROM get_object_fields;

它返回此错误:

  

错误:RETURN在函数返回集中没有参数;
  在“QUERY”或其附近使用RETURN NEXT

3 个答案:

答案 0 :(得分:10)

修复错误@Pavel already pointed out后,还要正确定义返回类型,或者每次调用时都必须提供列定义列表。

这个电话:

SELECT * FROM get_object_fields()

要求Postgres知道如何扩展 * 。由于您要返回匿名记录,因此您将获得例外:

  

错误:返回函数需要列定义列表   "记录"

解决这个问题的一种方法是RETURNS TABLE(Postgres 8.4 +):

CREATE OR REPLACE FUNCTION get_object_fields()
  RETURNS TABLE (department_id int) AS 
$func$
BEGIN
   RETURN QUERY
   SELECT department_id
   FROM   fact_department_daily 
   WHERE  report_date = '2013-06-07';
END
$func$ LANGUAGE plpgsql;

适用于SQL函数。

这个密切相关答案的更多细节和链接:
PostgreSQL: ERROR: 42601: a column definition list is required for functions returning "record"

答案 1 :(得分:3)

我看到更多错误:

首先,SET RETURNING FUNCTIONS调用具有以下语法

SELECT * FROM get_object_fields()

秒 - RETURN QUERY将查询结果直接转发给输出。你不能将这个结果存储到变量中 - 现在在PostgreSQL中是不可能的。

BEGIN
  RETURN QUERY SELECT ....; -- result is forwarded to output directly
  RETURN;   -- there will not be any next result, finish execution
END;

第三 - 这些简单的函数最好用SQL语言实现

CREATE OR REPLACE FUNCTION get_object_fields()
RETURNS SETOF RECORD AS $$
SELECT department_id WHERE ...
$$ LANGUAGE sql STABLE;

答案 2 :(得分:0)

这是一种方式

drop function if exists get_test_type();

drop type if exists test_comp;
drop type if exists test_type;
drop type if exists test_person;

create type test_type as (
  foo int, 
  bar int
);

create type test_person as (
  first_name text, 
  last_name text
);

create type test_comp as 
(
  prop_a test_type[], 
  prop_b test_person[]
);


create or replace function get_test_type()
returns test_comp
as $$
declare
  a test_type[];
  b test_person[];
  x test_comp;
begin

  a := array(
    select row (m.message_id, m.message_id) 
    from message m
  );

  -- alternative 'strongly typed'
  b := array[
    row('Bob', 'Jones')::test_person,
    row('Mike', 'Reid')::test_person
  ]::test_person[];

  -- alternative 'loosely typed'
  b := array[
    row('Bob', 'Jones'),
    row('Mike', 'Reid')
  ];

  -- using a select
  b := array (
    select row ('Jake', 'Scott')
    union all 
    select row ('Suraksha', 'Setty')
  );  

  x := row(a, b);

  return x;  
end;
$$
language 'plpgsql' stable;


select * from get_test_type();