I'm trying to create a before update trigger for a table. Basically, on each row update I need to set additional column on the same row on the same table.
However, for some reason, each trigger call results in setting values from a previous trigger call.
Here's the code for my trigger:
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();
The select statement inside the test_trigger_func function works correctly when run outside the function. But the raise notice statements show incorrect (previous) values when the select is called from inside the test_trigger_func function.
The salesprofile.solutionscreteria #>> '{departments, 0}' statement contains the id for the row in the department table. And I'm trying to set the department column on the salesprofile table row from the "department".name on each salesprofile row update (by modifying NEW.department = ...).
The behaviour I get:
the
selectstatement is perfectly fine and works as expected (when called as is, outside the function).when I make the very first update to the
salesprofilerow, the trigger sets thedepartmentcolumn asNULL(the column does not get updated at all);when I make the second update to the
salesprofilerow, the trigger sets thedepartmentcolumn as the value that I was trying to set on the first update;when I make the third update to the
salesprofilerow, the trigger sets thedepartmentcolumn as the value that I was trying to set on the second update;and so on...
if I put the incorrect value to the
salesprofile.solutionscreteria #>> '{departments, 0}'value, the first trigger update will not cause any errors.and then if I set the correct value after that, the trigger will fire with an error (caused by the previous trigger call with incorrect value).
I don't get how and why this is happening and I do hope I'm explaining the behaviour in an intelligible way.
Is this the expected behaviour for potgresql triggers? If not, then could you explain what's happening and how to make it work correctly?
It is a
BEFOREtrigger so it occurs before thesalesprofiletable has theNEWdata. I'm not entirely following but I'm go to say that thissalesprofile.solutionscreteria #>> '{departments, 0}'is using the existing(previous) row not the update data the trigger is running on. Try it withNEW.solutionscreteria.