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

Come restituire un valore da una stored procedure (non una funzione)?

Prova del concetto

Una PROCEDURE può valori di ritorno, ma in modo molto limitato (a partire da Postgres 13).

Il manuale su CALL :

Il manuale su CREATE PROCEDURE :

Quindi il tuo uso di INOUT la modalità è corretta. Ma manca l'assegnazione nel corpo della funzione. E alcune altre cose sono sbagliate/non ottimali. Suggerisco:

CREATE OR REPLACE PROCEDURE public.spproductinsertupdatedelete(
  _ser        int
, _subcategid int
, _inrprice   numeric
, _usdprice   numeric
, _colour     int
, _size       int
, _qty        int
, INOUT _prod_id int DEFAULT NULL
)
  LANGUAGE plpgsql AS
$proc$
BEGIN
   CASE _ser    -- simpler than IF
   WHEN 1 THEN  -- INSERT
      INSERT INTO product
             (prod_subcateg_id, prod_inr_price, prod_usd_price, prod_colour, prod_size, prod_qty)
      VALUES (_subcategid     , _inrprice     , _usdprice     , _colour    , _size    , _qty    )
      RETURNING prod_id
      INTO _prod_id;   -- !!!

   WHEN 2 THEN  -- UPDATE
      UPDATE product
      SET   (prod_subcateg_id, prod_inr_price, prod_usd_price, prod_size, prod_colour, prod_qty)
          = (_subcategid     , _inrprice     , _usdprice     , _size    , _colour    , _qty)
      WHERE  prod_id = _prod_id;

   WHEN 3 THEN  -- soft-DELETE
      UPDATE product
      SET    prod_datetill = now()
      WHERE  prod_id = _prod_id;

   ELSE
      RAISE EXCEPTION 'Unexpected _ser value: %', _ser;
   END CASE;
END
$proc$;

db<>violino qui

Prendi questo come prova del concetto. Ma non vedo nulla nella domanda che giustifichi l'uso di un PROCEDURE in primo luogo.

Probabilmente vuoi una FUNCTION

Una FUNCTION offre più opzioni per restituire i valori, non deve essere eseguito separatamente con CALL e può essere integrato in query più grandi. È probabile che sia quello che volevi in ​​primo luogo, e che tu sia stato solo fuorviato dal diffuso termine improprio "procedura archiviata". Vedi:

Inoltre, nella forma attuale, devi fornire molti parametri di rumore se vuoi aggiornare o cancellare una riga. I semplici comandi SQL potrebbero fare il lavoro. O funzioni separate...

La regola pratica :se non hai bisogno di gestire le transazioni dall'interno, probabilmente vorrai utilizzare una funzione anziché una procedura. Successivamente, le procedure di Postgres potrebbero essere estese per essere in grado di restituire più set di risultati (per standard SQL), ma non ancora (pag. 13).

Vedi: