简体   繁体   English

触发更新Postgres 9中的当前日期

[英]Trigger to update current date in Postgres 9

I have two tables called sale and customer . 我有两张叫做salecustomer桌子。 I want to create a trigger that updates the column last_purchase on customer table on each new insert in the sale table. 我想创建一个触发器来更新sale表中每个新插入的customer表上的last_purchase列。

Table customer: customer_id, name, last_sale, ... 表customer:customer_id,name,last_sale,...
Table sale: sale_id, customer_id, date, ... 表销售:sale_id,customer_id,日期,...

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

I have started writing but I don't know how to do it. 我已经开始写作,但我不知道该怎么做。
Could someone help me? 有人能帮助我吗?

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;

then 然后

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

NEW is the row which is about to be inserted in the sale table. NEW是即将插入销售表中的行。 (For an update row, it would be NEW for how the row will look after the update, and OLD for how the row looks before the update). (对于更新行,这将是NEW的行会怎么看更新后,和OLD该行的外观更新之前)。

Basically, I don't think it is a good idea to store redundant data. 基本上,我认为存储冗余数据不是一个好主意。 The last_sale column in customers is just an aggregate of max(sales.sale_date). 客户中的last_sale列只是max(sales.sale_date)的汇总。

It even gets worse if we use now() to touch customers.last_date. 如果我们使用now()来触摸customers.last_date,情况会更糟。 What would happen if we would need to re-insert some historical records (eg to recompute last year's taxes). 如果我们需要重新插入一些历史记录(例如重新计算去年的税收)会发生什么。 That's what you get when you store redundant data.... 这就是存储冗余数据时的结果....

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

The results: 结果:

 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)

I think you want the rule here. 我想你想要这个规则。

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 : but see the discussion in comments. 编辑 :但请参阅评论中的讨论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM