【问题标题】:Updating only last updated row using a function in PSQL使用 PSQL 中的函数仅更新最后更新的行
【发布时间】:2019-02-06 10:04:56
【问题描述】:

我正在开发一个函数,该函数将根据到达和离开时间计算工作时间。

我的函数如下所示:

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

【问题讨论】:

  • LIMIT 1 没有订单通常是没有意义的
  • 您实际上并不需要存储这些信息。从表中检索数据时,您可以轻松计算工作时间。
  • @a_horse_with_no_name 我知道,将工作时间存储在数据库中只是我的习惯,因为以后在报告中需要它。
  • 你能澄清你的问题吗?您是否希望它 (a) 重新计算 datum=current_date AND odlazak IS NOT NULL AND DOLAZAK IS NOT NULL 的所有行的“工作时间”,(b) 仅更新您更新的行(“如果我手动尝试更改一行的离开”),或者 (c)其他的?
  • @eurotrash 已更新。问题是,在我通过 C# 应用程序进行手动或自动更新后,我希望我的触发器计算通过添加 odlazak 或离开更新的行的工作时间。该行唯一的独特之处在于他的 id_radni_sati

标签: postgresql function timestamp database-trigger


【解决方案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');

表格如下:

现在更新:

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;

【讨论】:

  • 非常感谢,是的,这就是我的问题的解决方案 =)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-20
  • 1970-01-01
  • 2022-01-08
  • 2020-09-25
相关资源
最近更新 更多