0

我正在尝试为before update表创建触发器。基本上,在每次更新行时,我都需要在同一张表的同一行上设置额外的列。

但是,由于某种原因,每个触发器调用都会导致从前一个触发器调用中设置值。

这是我的触发器的代码:

create or replace function test_trigger_func() returns trigger as $$
    declare
        v_department  text;
    begin
        select department.name into v_department
        from salesprofile
        left join (
           select department.name from salesprofile join department on department.id = (
               salesprofile.solutionscreteria #>> '{departments, 0}'
           )::int4 where salesprofile.id = NEW.id
        ) department on true
        where salesprofile.id = NEW.id
        group by department.name;
        
        NEW.department = v_department;
        
        raise notice 'DEP: %', v_department;
        raise notice 'NEW DEP: %', NEW.department;
        
        return NEW;
    end;
$$ language plpgsql;

drop trigger if exists test_trigger on salesprofile;

create trigger test_trigger before update on salesprofile
for each row execute procedure test_trigger_func();

在函数外部运行时,函数内部的select语句test_trigger_func可以正常工作。但是当从函数内部调用时,这些raise notice语句显示不正确的(以前的)值。selecttest_trigger_func

salesprofile.solutionscreteria #>> '{departments, 0}'语句包含表id中的行department。我正在尝试从每行更新(通过修改)设置表格行department上的列。salesprofile"department".namesalesprofileNEW.department = ...


我得到的行为:

  • select语句非常好并且按预期工作(按原样调用时,在函数之外)。

  • 当我对salesprofile行进行第一次更新时,触发器将department列设置为NULL(该列根本没有更新);

  • 当我对salesprofile行进行第二次更新时,触发器将department列设置为我在第一次更新时尝试设置的值;

  • 当我对行进行第三次更新时salesprofile,触发器将department列设置为我在第二次更新时尝试设置的值;

  • 等等...

  • 如果我将不正确的值放入salesprofile.solutionscreteria #>> '{departments, 0}'值中,第一次触发更新不会导致任何错误。

  • 然后如果我在此之后设置正确的值,触发器将触发错误(由上一个触发器调用的值不正确引起)。


我不明白这是如何以及为什么会发生的,我希望我能以一种可以理解的方式解释这种行为。

这是 potgresql 触发器的预期行为吗?如果没有,那么您能否解释发生了什么以及如何使其正常工作?

4

1 回答 1

1

它是一个BEFORE触发器,因此它在salesprofile表有NEW数据之前发生。我并不完全遵循,但我想说这salesprofile.solutionscreteria #>> '{departments, 0}'是使用现有(上一个)行而不是触发器正在运行的更新数据。试试看NEW.solutionscreteria

于 2021-08-17T15:17:39.070 回答