我正在尝试为表创建一个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();
test_trigger_func
函数内部的select
语句在函数外部运行时正常工作。但是,当从test_trigger_func
函数内部调用select
时,raise notice
语句显示不正确的(先前)值。
salesprofile.solutionscreteria #>> '{departments, 0}'
语句包含department
表中行对应的id
。我试图在salesprofile
行更新上从"department".name
设置salesprofile
表行上的department
列(通过修改NEW.department = ...
)。
我得到的行为:
select
语句非常好,并按预期工作(在函数外部按原样调用时)。当我对
salesprofile
行进行第一次更新时,触发器将department
列设置为NULL
(列根本不更新);当我对
salesprofile
行进行第二次更新时,触发器将department
列设置为我试图在第一次更新时设置的值;当我对
salesprofile
行进行第三次更新时,触发器将department
列设置为我试图在第二次更新时设置的值;等等…
如果我将不正确的值设置为
salesprofile.solutionscreteria #>> '{departments, 0}'
值,第一次触发更新将不会导致任何错误。,然后如果我在此之后设置正确的值,触发器将触发一个错误(由先前的触发器调用不正确的值引起)。
我不明白这是如何发生的,为什么会发生,我希望我能以一种可理解的方式解释这种行为。
这是potgresql触发器的预期行为吗?如果没有,你能解释一下发生了什么,以及如何使它正确工作吗?
这是一个BEFORE
触发器,所以它发生在salesprofile
表具有NEW
数据之前。我不完全遵循,但我要说的是,这个salesprofile.solutionscreteria #>> '{departments, 0}'
是使用现有的(前)行,而不是触发器正在运行的更新数据。试试NEW.solutionscreteria
。