PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Como retornar um valor de um procedimento armazenado (não função)?

Prova de conceito


Um PROCEDIMENTO pode valores de retorno, mas de forma muito limitada (a partir do Postgres 13).

O manual sobre CALL :

O manual sobre CREATE PROCEDURE :

Portanto, seu uso do INOUT modo está correto. Mas a atribuição no corpo da função está ausente. E algumas outras coisas estão erradas / abaixo do ideal. Eu sugiro:
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<>fiddle aqui

Tome isso como prova de conceito. Mas não vejo nada na pergunta que justifique o uso de um PROCEDURE em primeiro lugar.

Você provavelmente quer uma FUNCTION


Uma FUNÇÃO oferece mais opções para retornar valores, não precisa ser executado separadamente com CALL , e pode ser integrado em consultas maiores. As chances são de que isso é o que você queria em primeiro lugar, e você estava apenas sendo enganado pelo equívoco generalizado "procedimento armazenado". Ver:

Além disso, no formulário atual, você precisa fornecer muitos parâmetros de ruído se quiser atualizar ou excluir uma linha. Comandos SQL simples podem fazer o trabalho. Ou funções separadas...

A regra de ouro :se você não precisar gerenciar transações de dentro, provavelmente desejará usar uma função em vez de um procedimento. Mais tarde, os procedimentos do Postgres podem ser estendidos para poder retornar vários conjuntos de resultados (por padrão SQL), mas ainda não (pág. 13).

Ver: