Setting variable in a Postgres function

时间:2018-03-25 19:23:05

标签: sql postgresql function variable-assignment plpgsql

CREATE OR REPLACE FUNCTION "freeTicket" (eid integer NOT NULL)

DECLARE
    couponCode text 
BEGIN


INSERT INTO purchases p (cid, pdate, eid, ccode) 
VALUES
(
  SELECT p.cid, GETDATE(), $1, couponCode FROM purchase p
  GROUP BY p.cid
 HAVING COUNT(1) > 5
  ORDER BY p.cid
);

END; LANGUAGE plpgsql;

I need to set the variable of couponCode to the output of:

Select code from couponCode where eid = $1 and percentage = 100; 

And use it in the insert query above.
What is the best way to do this?

2 个答案:

答案 0 :(得分:1)

That would be SELECT <expressions> INTO <variables> FROM ..., but you can do it all in one statement:

INSERT INTO purchases p (cid, pdate, eid, ccode) 
   SELECT p.cid,
          current_date,
          $1,
          (SELECT code FROM couponcode
           WHERE eid = $1 AND percentage = 100)
   FROM purchase p
   GROUP BY p.cid
   HAVING COUNT(1) > 5:

ORDER BY makes no sense here.

答案 1 :(得分:0)

关于在PL / pgSQL中分配变量的基础知识:

除此之外,您的函数还有许多语法错误和其他问题。从:

开始
CREATE OR REPLACE FUNCTION "freeTicket" (eid integer NOT NULL)

DECLARE ...
  • NOT NULL此处不是有效的语法。
  • 您必须以某种方式声明返回类型 。如果该函数未返回任何内容,请添加RETURNS void
  • 为了您自己的利益,请避免使用Postgres中的CaMeL案例标识符。如果可能,请仅使用合法的小写标识符。参见:

该功能可以这样工作:

CREATE OR REPLACE FUNCTION free_ticket(_eid integer, OUT _row_ct int) AS
$func$
DECLARE
   coupon_code text;  -- semicolon required
BEGIN
   INSERT INTO purchases (cid, pdate, eid, ccode)
   SELECT cid, now()::date, _eid
       , (SELECT code FROM couponCode WHERE eid = _eid AND percentage = 100)
   FROM   purchase
   GROUP  BY cid
   HAVING COUNT(*) > 5  -- count(*) is faster
   ORDER  BY cid;       -- ORDER BY is *not* pointless.

   GET DIAGNOSTICS _row_ct := ROW_COUNT;
END
$func$  LANGUAGE plpgsql;

自动在函数末尾返回添加的OUT row_ct int。它不需要明确的RETURNS声明。

您还有一个表别名:

INSERT INTO purchases p (cid, pdate, eid, ccode)

但是INSERT statements require the AS keyword for aliases以避免歧义(与其他DML语句不同)。所以:INSERT INTO purchases AS p ...。但不需要别名,因为声明中没有歧义。

相关:

旁白:两个名为purchasepurchases的表格,必然会导致混淆。第二个表格也可以替换为VIEWMATERIALIZED VIEW