Postgres - 使用匹配键触发

时间:2015-12-03 03:34:31

标签: postgresql triggers

我有几张桌子。表cexp是一个具有cid和total属性的表。 Cid被分组,总数是该cid的数量*价格的总和(在cid上匹配)

cexp表填充了以下代码的结果:

SELECT c.cid, sum(ol.quantity*b.price) as total
FROM customers c join orders o on c.cid=o.cid
                       join orderlist ol on o.ordernum=ol.ordernum
                       join books b on b.isbn=ol.isbn
GROUP BY C.CID

我的任务是创建一个触发器,当为订单和订单列表插入行时,在cexp中找到匹配的名称,并将现有总数增加新数量(来自订单列表)和价格(来自书籍)的乘积。如果不匹配,请在cexp中插入一行。

表格如下:

Customers-cid,name pk-cid

书籍 - isbn,title,price pk-isbn

订单 - ordernum,cid pk-ordernum

订单 - ordernum,isbn,数量 - pk-(ordernum,isbn)

cexp - cid,total - pk-cid

我收到语法错误。任何人都可以更正此代码吗?

CREATE OR REPLACE FUNCTION cexpupd()
RETURNS trigger as 
$cexpupd$
BEGIN
UPDATE cexp
SET new.total=total+Select (b.price*new.quantity) FROM customers c
 join orders o on c.cid=o.cid
 join orderlist ol on o.ordernum=ol.ordernum
 join books b on b.isbn=ol.isbn
 where b.isbn=new.isbn;
 --INSERT CODE WHEN ABOVE LINE DOES NOT OCCUR -INSERTS NEW ROW INTO CEXP
 END;
 $cexpupd$ 
 LANGUAGE plpgsql

1 个答案:

答案 0 :(得分:0)

我会说你的 UPDATE 声明是一个不可救药的鸟巢。幸运的是,有一种更简单的方法可以获得相同的结果。

请记住,触发器函数是过程代码,因此在单个语句中不需要concurrently load the gun, pull the trigger, scream, and shoot yourself in the foot。您可以访问所有程序性好处,如局部变量和流控制语句。

以下内容应该为您提供一个良好的开端:

CREATE OR REPLACE FUNCTION cexpupd()
  RETURNS trigger as 
  $cexpupd$
    DECLARE
      bookprice     books.price%TYPE;
      ext_total     cexp.total%TYPE;
      custid        orders.cid%TYPE;

    BEGIN
      SELECT cid
        INTO custid
        FROM orders
        WHERE orders.ordernum = NEW.ordernum;

      SELECT price
        INTO bookprice
        FROM books
        WHERE books.isbn = NEW.isbn;

      ext_total = bookprice * NEW.quantity;

      UPDATE cexp
        SET total = ext_total
        WHERE cid = custid;
      IF NOT FOUND THEN
        --INSERT new CID record here
        INSERT INTO cexp
            (cid, total)
          VALUES
            (custid, ext_total);
      END IF;

      RETURN NEW;
    END;
  $cexpupd$ 
  LANGUAGE plpgsql;

注意结尾附近的语句,RETURN NEW;这一行至关重要,因为它是PostgreSQL触发器函数告诉数据库继续执行触发触发器的语句的方式。

如果您需要任何澄清,请不要犹豫。请注意我没有尝试过执行此函数,但我确实创建了必要的表来成功编译它。