Postgresql触发器功能,用于根据最近的时间戳设置列中的值

时间:2014-06-08 16:57:05

标签: postgresql triggers plpgsql postgresql-9.3

我在postgresql中创建触发器功能时遇到了麻烦,应该执行以下操作:

我有一个带有类别(varchar),edit_date(时间戳)和实际(布尔值)的表。

我已经有一个触发器,用于设置UPDATE或INSERT的实际时间戳。列'实际'如果此edit_date是类别的最新版本,则应该说“TRUE”。因此,当a类中有两个实体时,具有最新edit_date的实体应设置为TRUE,而此类别中的另一个应设置为FALSE。

非常感谢你的帮助,我非常感谢你。 最好

1 个答案:

答案 0 :(得分:0)

更新触发器中同一个表的其他行非常棘手,因为它会导致递归触发器调用。一般来说,你应该避免这样的解决方案。重新思考您的数据模型,并考虑是否真的需要actual字段。您始终可以在此类查询中选择实际行(我假设my_table已将字段id作为主键):

select distinct on(category) id, category, edit_date
from my_table
order by 2, 3 desc;

但是,如果字段actual是必需的,您可以创建一个函数,并在my_table上的任何更改后或仅在需要时使用它:

create or replace function set_my_table_actual ()
returns void language sql
as $$
update my_table t
set 
    actual = (
        t.id = any (
            select x.id
            from (
                select distinct on(category) id, category, edit_date
                from my_table
                order by 2, 3 desc
                ) x
        )
    );
$$;

好吧,如果你绝对想要一个触发器,你可以使用pg_trigger_depth()函数(在Postgres 9.2中引入):

create or replace function my_trigger()
returns trigger language plpgsql
as $$
begin
    if pg_trigger_depth() = 1 then
        perform set_my_table_actual ();
    end if;
    return null;
end $$;

create trigger my_trigger 
after insert or update or delete
on my_table for each statement 
execute procedure my_trigger();