创建触发器以获取时间戳之间的每小时差异

时间:2021-02-11 04:24:53

标签: postgresql

我有一个表格,我想在其中计算插入一行后两列之间的时间差(以小时为单位)。每当对表执行插入或更新时,我想设置一个触发器来执行此操作。

我的列是 delay_start、delay_stop 和 delay_duration。我想执行以下操作:

delay_duration = delay_stop - delay_start

结果应该是数字 (4,2) 值并进入 delay_duration 类别。以下是我到目前为止的内容,但由于某种原因它不会填充该列。

BEGIN
INSERT INTO public.deckdelays(delay_duration)
VALUES(DATEDIFF(hh, delay_stop, delay_start));
RETURN NEW;
END;

我对这一切都很陌生,所以如果有人能提供帮助,我将不胜感激!

1 个答案:

答案 0 :(得分:1)

如果您有 Postgres 12 或更高版本,您可以将 delay_duration 定义为生成的列。这可以让您消除触发器。

create table deckdelays(id           integer generated always as identity
                       , delay_start timestamp   
                       , delay_stop  timestamp
                       , delay_duration numeric(4,2)
                              generated always as 
                              ( extract(epoch from (delay_stop - delay_start))/3600 )
                              stored
                        --, other attributes
                       ); 

demo here


但如果你坚持触发:

create or replace 
function delayduration_func()
 returns trigger 
language plpgsql 
as $$
begin
    new.delay_duration = (extract(epoch from (deckdelays.delay_stop - deckdelays.delay_start))/3600)::numeric;
return new;
end;
$$;

create trigger delaydurationset1
before insert 
    or update of delay_stop, delay_start 
    on deckdelays
execute procedure delayduration_func();

变化:

  • 在触发之前而不是之后。一个 before 触发器可以修改 没有附加 DML 语句的列中的值,一个 after 触发器不能。在触发器中的表上发出 DML 语句 在同一张桌子上可能会导致所有类型的问题。它是韧皮的 尽可能避免。
  • 触发器名称和函数名称不一样。可能只是我,但我 不喜欢同名的不同事物。虽然它有效 往往会导致混乱。如果可能,请始终避免混淆。
  • 在更新 delay_start 时触发触发器。 delay_start 或 delay_end 的更新也会更新 delay_duration。