PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Argomento facoltativo nella funzione PL/pgSQL

A partire da PostgreSQL 8.4 (che sembra essere in esecuzione), ci sono valori predefiniti per i parametri delle funzioni . Se metti il ​​tuo parametro per ultimo e fornisci un valore predefinito, puoi semplicemente ometterlo dalla chiamata:

CREATE OR REPLACE FUNCTION foofunc(_param1 integer
                                 , _param2 date
                                 , _ids    int[] DEFAULT '{}')
  RETURNS SETOF foobar         -- declare return type!
  LANGUAGE plpgsql AS
$func$
BEGIN  -- required for plpgsql
   IF _ids <> '{}'::int[] THEN  -- exclude empty array and NULL
      RETURN QUERY
      SELECT *
      FROM   foobar
      WHERE  f1 = _param1
      AND    f2 = _param2
      AND    id = ANY(_ids);    -- "IN" is not proper syntax for arrays
   ELSE
      RETURN QUERY
      SELECT *
      FROM   foobar
      WHERE  f1 = _param1
      AND    f2 = _param2;
   END IF;
END  -- required for plpgsql
$func$;

Punti principali:

  • La parola chiave DEFAULT viene utilizzato per dichiarare i parametri predefiniti. Breve alternativa:= .

  • Ho rimosso il param1 ridondante dall'esempio disordinato.

  • Dal momento che restituisci SELECT * FROM foobar , dichiara il tipo di reso come RETURNS SETOF foobar invece di RETURNS SETOF record . Quest'ultimo modulo con record anonimi è molto ingombrante, dovresti fornire un elenco di definizioni di colonna ad ogni chiamata.

  • Uso un array di numeri interi (int[] ) come parametro di funzione. Adattato il IF espressione e il WHERE clausola di conseguenza.

  • IF le istruzioni non sono disponibili in semplice SQL. Deve essere LANGUAGE plpgsql per quello.

Chiama con o senza _ids :

SELECT * FROM foofunc(1, '2012-1-1'::date);

In effetti lo stesso:

SELECT * FROM foofunc(1, '2012-1-1'::date, '{}'::int[]);

Devi assicurarti che la chiamata non sia ambigua. Se hai un'altra funzione con lo stesso nome e due parametri, Postgres potrebbe non sapere quale scegliere. Il casting esplicito (come dimostro) lo restringe. Altrimenti, anche le stringhe letterali non tipizzate funzionano, ma essere espliciti non fa mai male.

Chiama da un'altra funzione:

CREATE FUNCTION foofuncwrapper(_param1 integer, _param2 date)
  RETURNS SETOF foobar
  LANGUAGE plgpsql AS
$func$
DECLARE
   _ids int[] := '{1,2,3}';
BEGIN
   -- whatever

   RETURN QUERY
   SELECT * FROM foofunc(_param1, _param2, _ids);
END
$func$;