Триггер для обновления текущей даты в Postgres 9 - PullRequest
3 голосов
/ 13 декабря 2011

У меня есть две таблицы с именами sale и customer. Я хочу создать триггер, который обновляет столбец last_purchase в таблице customer при каждой новой вставке в таблицу sale.

Таблица customer: customer_id, name, last_sale, ...
Продажа таблицы: sale_id, customer_id, date, ...

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

Я начал писать, но не знаю, как это сделать.
Может ли кто-нибудь мне помочь?

Ответы [ 3 ]

6 голосов
/ 13 декабря 2011
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 для того, как строка будет выглядеть до обновления).

2 голосов
/ 14 декабря 2011

В принципе, я не думаю, что это хорошая идея для хранения избыточных данных. Столбец last_sale в клиентах - это всего лишь агрегат max (sales.sale_date).

Это даже ухудшится, если мы используем now () для прикосновения к customer.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)
0 голосов
/ 13 декабря 2011

Я думаю, вы хотите здесь правило.

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

РЕДАКТИРОВАТЬ : но см. Обсуждение в комментариях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...