使用PSQL中的函数仅更新上次更新的行

问题描述 投票:0回答:1

我正在开发一个功能,可以计算出发和离开时间的工作时间。

我的功能看起来像这样:

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时,如何计算数据库中的单行工作时间(需要更新的工作时间)?

postgresql function timestamp database-trigger
1个回答
1
投票

问题在于触发器功能中的更新语句。它应该使用更新的行的id来确保它只更新正确的记录。

这是设置:

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

表看起来像这样:

enter image description here

现在更新:

UPDATE t SET departure = NOW() + INTERVAL '2 hours' WHERE id = 2;

表现在是:

enter image description here


所以在你的情况下你应该改变

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;
© www.soinside.com 2019 - 2024. All rights reserved.