PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Type de retour pour la fonction avec array_agg()

Une fonction doit déclarer un type de retour. Un tableau ne peut être basé que sur un type d'élément bien connu. Un enregistrement anonyme n'est pas autorisé. Créez donc un type composite qui correspond à vos besoins (sauf s'il existe déjà une table ou une vue définissant le type de ligne).

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

À des fins de test, vous pouvez également créer une table temporaire pour enregistrer un type composite pour la durée d'une session :

CREATE TEMP TABLE my_type ( ...)

(Une table temporaire est supprimée à la fin de la session, toute fonction basée sur le type serait ensuite interrompue.)

Utilisez-le comme type de base pour le tableau. Vous pouvez utiliser une fonction SQL simple à cet effet :

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;

Appel :

SELECT foo();

Alternative simple avec text[]

Vous pouvez également caster en text / text[] . Vous perdez les noms de colonne et les informations de type, mais cela fonctionne immédiatement :

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

Si vous n'avez pas réellement besoin d'un tableau, vous pouvez supprimer array_agg() , retournez des lignes individuelles et déclarez le type de retour avec RETURNS TABLE (...) . Recherchez SO pour le tag, vous trouverez de nombreux exemples ..

N'oubliez pas d'appeler une fonction renvoyant un ensemble avec :

SELECT * FROM foo();