2011-12-13 7 views
2

salecustomerという2つのテーブルがあります。私はsaleテーブルの各新しい挿入のlast_purchaseの列をcustomerテーブルに更新するトリガーを作成したいと思います。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

トリガーの作成は動作しません、その最後の行はする必要があります...それぞれの ROW EXECUTE PROCEDURE update_customer_last_sale(); 少なくともポストグル10の場合。 –

-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); 

EDIT:しかし、コメント欄での議論を参照してください。

+0

ルールは非常に難しいので、正しく使用するにはそれらをよく理解しておく必要があります。 COPYを使用してデータを挿入するときにも機能しません。 –

+0

@FrankHeikensは、あなたが使用するものを理解することは珍しくない、私はトリガーを理解することも傷つけないと言っています;-) –

+0

ルールは幾分廃止され、トリガーを使用するという明確な勧告がPostgresチームからあります。 –

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) 
関連する問題