Обновление только последней обновленной строки с использованием функции в PSQL
Я работаю над функцией, которая будет рассчитывать рабочее время от времени прибытия и отъезда.
Моя функция выглядит так:
CREATE FUNCTION Sati_rada()
RETURNS TRIGGER
as $Update$
BEGIN
update radni_sati
set sati_rada=(select (current_date + (odlazak-dolazak))
from radni_sati
where datum=current_date
and dolazak IS NOT NULL
LIMIT 1)
WHERE datum=current_date
AND odlazak IS NOT NULL
AND DOLAZAK IS NOT NULL;
RETURN NULL;
END $Update$
language plpgsql;
Мой триггер выглядит так:
CREATE TRIGGER Sati_rada_trigger
AFTER UPDATE OF odlazak ON radni_sati
FOR EACH ROW EXECUTE PROCEDURE Sati_rada();
Проблема начинается здесь, когда я хочу использовать функцию в последней строке, которую я обновил вручную.
Например (я перевел названия столбцов с моего родного языка):
SELECT id_radni_sati as id,ime as name,dolazak as arrival,
odlazak as departure, sati_rada as "hours of work" FROM radni_sati
WHERE datum='31/08/2018';
id | name | arrival | departure | hours of work
-------+---------+---------------------+---------------------+---------------------
22282 | Nevenko | 2018-08-31 07:00:00 | |
22284 | Marko | 2018-08-31 11:41:52 | 2018-08-31 12:01:45 | 2018-08-31 00:19:53
Если я вручную попытаюсь изменить отправление одной строки:
UPDATE radni_sati SET odlazak='31/08/2018 07:05:00' where id_radni_sati=22282;
Это происходит:
postgres=# select id_radni_sati as id,ime as name,dolazak as arrival,
odlazak as departure, sati_rada as "hours of work" from radni_sati
where datum='31/08/2018';
id | name | arrival | departure | hours of work
-------+---------+---------------------+---------------------+---------------------
22282 | Nevenko | 2018-08-31 07:00:00 | 2018-08-31 07:05:00 | 2018-08-31 00:05:00
22284 | Marko | 2018-08-31 11:41:52 | 2018-08-31 12:01:45 | 2018-08-31 00:05:00
(2 rows)
Мой вопрос: Как рассчитать рабочие часы для одной строки в базе данных (той, которая нуждается в обновлении) каждый раз, когда обновляется столбец odlazak?
1 ответ
Проблема связана с вашим оператором обновления в вашей функции триггера. Он должен использовать обновленный идентификатор строки, чтобы убедиться, что он только обновляет правильную запись.
Вот настройки:
CREATE TABLE t (id INTEGER, arrival TIMESTAMP, departure TIMESTAMP, hours_of_work TIME);
CREATE OR REPLACE FUNCTION public.trig()
RETURNS TRIGGER AS $$
BEGIN
UPDATE t
SET hours_of_work = NEW.departure - NEW.arrival
WHERE id = NEW.id;
RETURN NULL;
END
$$ LANGUAGE plpgsql;
CREATE TRIGGER t_trig
AFTER UPDATE OF departure ON public.t
FOR EACH ROW EXECUTE PROCEDURE public.trig();
INSERT INTO t VALUES (1, NOW(), NOW() + INTERVAL '1 hour', (NOW() + INTERVAL '1 hour') - NOW());
INSERT INTO t VALUES (2, NOW(), NOW() + INTERVAL '1 hour');
Таблица выглядит так:
Теперь обновление:
UPDATE t SET departure = NOW() + INTERVAL '2 hours' WHERE id = 2;
И таблица сейчас:
Так что в вашем случае вы должны изменить
update radni_sati set sati_rada=(select (current_date + (odlazak-dolazak)) from radni_sati where datum=current_date and dolazak IS NOT NULL LIMIT 1) WHERE datum=current_date AND odlazak IS NOT NULL AND DOLAZAK IS NOT NULL;
в
UPDATE radni_sati
SET sati_rada = current_date + (NEW.odlazak - NEW.dolazak)
WHERE id_radni_sati = NEW.id_radni_sati;