簡體   English   中英

function 與 array_agg() 的返回類型

[英]Return type for function with array_agg()

我正在嘗試創建一個返回字符串數組的 function,我可以在沒有 function 的情況下執行此操作並返回record[]類型,當我嘗試在 function 中返回該類型的結果時,它說不是支持的。

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
$$

表格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

我想返回一個text[]但我找不到使此查詢成為文本類型或字符串的方法。

我想返回這樣的東西:

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

一個函數需要聲明一個返回類型。 數組只能基於眾所周知的元素類型。 不允許匿名記錄。 所以創建一個適合您需要的復合類型(除非有一個表或視圖已經定義了行類型)。

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

出於測試目的,您還可以創建一個臨時表來在會話期間注冊復合類型:

CREATE TEMP TABLE my_type ( ...)

(在會話結束時刪除一個臨時表,此后建立在該類型上的任何函數都將被破壞。)

將其用作數組的基本類型。 您可以使用一個簡單的 SQL 函數來實現:

CREATE OR REPLACE FUNCTION foo()
  RETURNS my_type[] AS
$func$
SELECT array_agg(result::my_type)  -- you must cast the row type!
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;

致電:

SELECT foo();

text[]簡單替代

您還可以轉換為text / text[] 您丟失了列名和類型信息,但它開箱即用:

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

如果您實際上不需要數組,則可以廢棄array_agg() ,返回單個行並使用RETURNS TABLE (...)聲明返回類型。 搜索標簽,你會發現很多例子..

請記住使用以下命令調用設置返回函數:

SELECT * FROM foo();

基於 Erwin's great answer(in the same page) 的小優化:
--create table: create table judgements(id integer, sampleid integer, alterlevel integer, judgements_timestamp timestamp with time zone );

--創建類型:

create type judgements_type as(
   ts text, alterlevel int, time_Passed interval
);

完整 function:

create or replace function alarm_event_list
(_sampleid integer,
 starttime timestamp without time zone, 
stoptime timestamp without time zone)
returns judgements_type[] as
$body$
select array_agg(result::judgements_type) from
(select to_char(judgements_timestamp,'YYYY-MM-DD HH24:MI:SS'),
      alterlevel,
     coalesce( judgements_timestamp - lag(judgements_timestamp)
         over (order by judgements_timestamp), make_interval(0,0,0))
from judgements
where  sampleid = _sampleid
and alterlevel > 0
and judgements_timestamp >= starttime
and judgements_timestamp <= stoptime) result;
$body$ language sql;

select * from alarm_event_list(11, '2013-09-17 00:00:00', '2013-09-17 23:59:59'); 將返回一個聚合數組。
使其成為 jsonb:

select * from to_jsonb(
    alarm_event_list(11, '2013-09-17 00:00:00', '2013-09-17 23:59:59'));

將其設為 2 行,並帶有分隔的 json 文本:

CREATE OR REPLACE FUNCTION public.array_transport(all_items anyarray)
 RETURNS SETOF text
 LANGUAGE plpgsql
 STRICT
AS $function$
declare
  item  record;
begin
foreach   item  in array all_items
loop
   return next(to_json(item)::text);
   end loop;
end;
$function$

然后

select * from array_transport
    (alarm_event_list(11, '2013-09-17 00:00:00', '2013-09-17 23:59:59'));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM