Return type for function with array_agg()

我怕爱的太早我们不能终老 提交于 2019-12-08 02:04:35

问题


I'm trying to create a function that returns an array of string, I'm able to do it without a function and returns a record[] type, when i try to return that type of result in the function it says that is not supported.

CREATE OR REPLACE FUNCTION alarmEventList(sampleid integer
                         , starttime timestamp without time zone
                         , stoptime timestamp without time zone)
RETURNS text[] AS
DECLARE
result record[];
BEGIN

select array_agg(result)
    from (select to_char("Timestamp", 'YYYY-MM-DD HH24:MI:SS'), "AlertLevel"
               , "Timestamp" - lag("Timestamp") over (order by "Timestamp")
          from "Judgements"
          WHERE "SampleID"=sampleid and "Timestamp" >= starttime
          and "Timestamp" <= stoptime) as result where "AlertLevel" >0;

return result;
END

Definition of Judgements
ID      | SampleID | AlertLevel | Timestamp               
integer | integer  | integer    | timestamp with time zone
   1    |    11    |    1       | 2013-09-17 10:36:40
   2    |    11    |    0       | 2013-09-17 10:36:45
   3    |    11    |    2       | 2013-09-17 10:36:51

I was thinking to return a text[] but I don't find the way to make this query a text type or string.

I want to return something like this:

{"2013-11-21 10:36:40, 1, 10", "etc...etc..."}

回答1:


A function needs to declare a return type. An array can only be built upon a well known base type. An anonymous record is not allowed. So create a composite type that fits your needs.

CREATE TYPE my_type (
  ts          text
 ,alertlevel  int
 ,time_passed interval
);

For testing purposes you can also create a temporary table to register a composite type for the duration of a session:

CREATE TEMP TABLE my_type ( ...)

The temp. table is dropped at the end of the session and any function building on the the type, will be broken after that.

Use that as base type for the array. You can use a simpler sql function for your purpose:

CREATE OR REPLACE FUNCTION foo()
  RETURNS my_type[] AS
$func$
SELECT array_agg(result::my_type)  -- you must cast the record!
FROM  (
   SELECT to_char("Timestamp", 'YYYY-MM-DD HH24:MI:SS')
          ,"AlertLevel"
          ,"Timestamp" - lag("Timestamp") OVER (ORDER BY "Timestamp")
   FROM   "Judgements"
   WHERE  "SampleID" = sampleid
   AND    "Timestamp" >= starttime
   AND    "Timestamp" <= stoptime
   ) result
WHERE "AlertLevel" > 0;
$func$
LANGUAGE sql;

Call:

SELECT foo();

Simple alternative with text[]

Of course you can also cast to text / text[]. You lose column names and type information, but it works out of the box:

CREATE OR REPLACE FUNCTION foo()
  RETURNS text[] AS
$func$
SELECT array_agg(result::text)  -- cast the record to text!
FROM  ( ... ) result
...;
$func$
LANGUAGE sql;

If you don't actually need an array, you can scrap array_agg(), return individual rows and declare the return type with RETURNS TABLE (...). Search on SO under the plpgsql tag, you'll find many examples ..

Remember to call such a function with:

SELECT * FROM foo();


来源:https://stackoverflow.com/questions/20228125/return-type-for-function-with-array-agg

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!