【发布时间】:2021-10-19 10:31:58
【问题描述】:
我正在尝试为表创建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}' 语句包含id 用于department 表中的行。我正在尝试在每个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吗? -
@AdrianKlaver 这确实成功了。您可以将此作为答案发布,我会将其标记为已接受。谢谢!
标签: sql postgresql triggers postgresql-10 postgresql-triggers