2011-12-13 56 views
2

我有兩個表salecustomer。我想創建一個觸發器,用於更新sale表中每個新插入的customer表上的last_purchase列。觸發器更新Postgres 9中的當前日期

表的客戶:CUSTOMER_ID,名稱,last_sale,...
表銷售:sale_id,CUSTOMER_ID,日期,...

CREATE TRIGGER update_last_sale BEFORE INSERT ON sale FOR EACH ROW EXECUTE... 

我已經開始寫,但我不知道該怎麼辦它。
有人可以幫助我嗎?

回答

4
CREATE FUNCTION update_customer_last_sale() RETURNS TRIGGER AS $$ 
BEGIN 
    UPDATE customer SET last_sale=now() WHERE cutomer_id=NEW.customer_id; 
    RETURN NEW; 
END; $$ 
LANGUAGE plpgsql; 

然後

CREATE TRIGGER update_last_sale 
BEFORE INSERT ON sale 
FOR EACH ROW EXECUTE update_customer_last_sale; 

NEW是大約是在銷售表中插入的行。 (對於更新行,這將是NEW關於更新後行的樣子,OLD關於行在更新前的樣子)。

+0

觸發創作不起作用,最後一行必須... FOR EACH ROW EXECUTE PROCEDURE update_customer_last_sale(); 至少爲postgres 10. – 2018-01-08 07:47:30

-1

我想你想在這裏的規則。

CREATE RULE therule AS ON INSERT TO sale DO ALSO 
    (UPDATE customer SET customer.last_sale = now() 
      WHERE customer.customer_id=NEW.customer_id); 

編輯:但見意見的討論。

+0

規則是非常棘手的,你必須非常好地理解它們才能正確使用它們。使用COPY插入數據時,它也不起作用! – 2011-12-13 19:10:12

2

基本上,我不認爲這是一個好主意,存儲冗餘數據。客戶中的last_sale列僅是max(sales.sale_date)的集合。

如果我們使用now()來觸碰customers.last_date,它甚至會變得更糟。如果我們需要重新插入一些歷史記錄(例如重新計算去年的稅收),會發生什麼情況。這時候,你存儲的冗餘數據,你會得到什麼....

-- modelled after Erwin's version 
SET search_path='tmp'; 

-- DROP TABLE customers CASCADE; 
CREATE TABLE customers 
    (id INTEGER NOT NULL PRIMARY KEY 
    , name VARCHAR 
    , last_sale DATE 
    ); 

-- DROP TABLE sales CASCADE; 
CREATE TABLE sales 
    (id INTEGER NOT NULL PRIMARY KEY 
    , customer_id INTEGER REFERENCES customers(id) 
    , saledate DATE NOT NULL 
    ); 


CREATE OR REPLACE FUNCTION update_customer_last_sale() RETURNS TRIGGER AS $meat$ 
BEGIN 
    UPDATE customers cu 
    -- SET last_sale = now() WHERE id=NEW.customer_id 
    SET last_sale = (
     SELECT MAX(saledate) FROM sales sa 
     WHERE sa.customer_id=cu.id 
     ) 
    WHERE cu.id=NEW.customer_id 
    ; 
    RETURN NEW; 
END; $meat$ 
LANGUAGE plpgsql; 

CREATE TRIGGER update_last_sale 
    AFTER INSERT ON sales 
    FOR EACH ROW 
    EXECUTE PROCEDURE update_customer_last_sale(); 


INSERT INTO customers(id,name,last_sale) VALUES(1, 'Dick', NULL),(2, 'Sue', NULL),(3, 'Bill', NULL); 


INSERT INTO sales(id,customer_id,saledate) VALUES (1,1,'1900-01-01'),(2,1,'1950-01-01'),(3,2,'2011-12-15'); 

SELECT * FROM customers; 

SELECT * FROM sales; 

結果:

id | name | last_sale 
----+------+------------ 
    3 | Bill | 
    1 | Dick | 1950-01-01 
    2 | Sue | 2011-12-15 
(3 rows) 

id | customer_id | saledate 
----+-------------+------------ 
    1 |   1 | 1900-01-01 
    2 |   1 | 1950-01-01 
    3 |   2 | 2011-12-15 
(3 rows)