如何从存储过程(而不是函数)返回值?

Kar*_*eya 1 postgresql stored-procedures plpgsql parameter-passing

我有一个插入、更新或删除表行的存储过程。当所有参数都用作输入时,它工作正常。但是,我需要返回最后插入行的 ID。为此,我尝试使用INOUT参数并在语句RETURNING之后INSERT返回 ID。

但是,我不知道如何将返回的 ID 绑定到参数INOUT。以下是存储过程的代码:

CREATE OR REPLACE PROCEDURE public.spproductinsertupdatedelete(
_ser integer,
_subcategid integer,
_inrprice numeric,
_usdprice numeric,
_colour integer,
_size integer,
_qty integer,
_prodid integer DEFAULT NULL::integer,
inout _pid integer default null
 )
LANGUAGE 'plpgsql'
AS $BODY$

BEGIN
  if _ser=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;

ELSEIF _ser=2 THEN
    
    UPDATE PRODUCT SET
    prod_subcateg_id = _subcategid,
    prod_inr_price = _inrprice,
    prod_usd_price = _usdprice,
    prod_size = _size,
    prod_colour = _colour,
    prod_qty=_qty
    where prod_id = _prodID;

ELSEIF _ser=3 THEN ---- Delete
    UPDATE PRODUCT SET prod_datetill = now()
    WHERE prod_id = _prodID;
    
end if;

END
$BODY$;
Run Code Online (Sandbox Code Playgroud)

在执行上述存储过程时,我收到此错误:

ERROR:  query has no destination for result data
Run Code Online (Sandbox Code Playgroud)

Erw*_*ter 7

概念证明

\n

A可以返回值,但方式非常有限(从 Postgres 13 开始)。PROCEDURE

\n

手册上CALL

\n
\n

CALL执行一个过程。

\n

如果该过程有任何输出参数,则将返回\n结果行,其中包含这些参数的值。

\n
\n

手册上CREATE PROCEDURE

\n
\n

argmode

\n

参数的模式:ININOUTVARIADIC。如果省略,则默认为IN。(OUT过程当前不支持参数。请INOUT改用。)

\n
\n

所以你使用的INOUT模式是正确的。但函数体中的赋值丢失了。还有其他一些事情是错误的/次优的。我建议:

\n
CREATE OR REPLACE PROCEDURE public.spproductinsertupdatedelete(\n  _ser        int\n, _subcategid int\n, _inrprice   numeric\n, _usdprice   numeric\n, _colour     int\n, _size       int\n, _qty        int\n, INOUT _prod_id int DEFAULT NULL\n)\n  LANGUAGE plpgsql AS\n$proc$\nBEGIN\n   CASE _ser    -- simpler than IF\n   WHEN 1 THEN  -- INSERT\n      INSERT INTO product\n             (prod_subcateg_id, prod_inr_price, prod_usd_price, prod_colour, prod_size, prod_qty)\n      VALUES (_subcategid     , _inrprice     , _usdprice     , _colour    , _size    , _qty    )\n      RETURNING prod_id\n      INTO _prod_id;   -- !!!\n\n   WHEN 2 THEN  -- UPDATE\n      UPDATE product\n      SET   (prod_subcateg_id, prod_inr_price, prod_usd_price, prod_size, prod_colour, prod_qty)\n          = (_subcategid     , _inrprice     , _usdprice     , _size    , _colour    , _qty)\n      WHERE  prod_id = _prod_id;\n\n   WHEN 3 THEN  -- soft-DELETE\n      UPDATE product\n      SET    prod_datetill = now()\n      WHERE  prod_id = _prod_id;\n\n   ELSE\n      RAISE EXCEPTION \'Unexpected _ser value: %\', _ser;\n   END CASE;\nEND\n$proc$;\n
Run Code Online (Sandbox Code Playgroud)\n

db<>在这里摆弄

\n

以此作为概念证明。PROCEDURE但我认为这个问题中没有任何东西值得首先使用 a 。

\n

你可能想要一个FUNCTION

\n

AFUNCTION提供了更多返回值选项,不需要与 单独运行CALL,并且可以集成到更大的查询中。很可能,这就是您最初想要的,而您只是被广泛使用的误称“存储过程”所误导。看:

\n\n

此外,在当前的形式中,如果要更新或软删除一行,则必须提供许多噪声参数。简单的 SQL 命令就可以完成这项工作。或者单独的功能...

\n

经验法则:如果您不需要从内部管理事务,您可能需要使用函数而不是过程。稍后,Postgres 过程可能会扩展为能够并返回多个结果集(根据 SQL 标准),但目前还没有(第 13 页)。

\n

看:

\n\n