问题
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