I am using an after update trigger in order recognize and log any changes made to records in the 'tasks' table. The column, and new and old value are all dynamic, so different every time.
This is what the trigger function looks like right now:
CREATE OR REPLACE FUNCTION fn_tasks_after_update()
RETURNS trigger
AS $BODY$
DECLARE
ri RECORD;
col_name TEXT;
BEGIN
FOR ri IN
SELECT column_name FROM information_schema.columns WHERE table_name = 'tasks'
LOOP
EXECUTE
'IF $1.' || ri.column_name || ' <> $2.' || ri.column_name || ' THEN
INSERT INTO tasks_log (task_id, type, "column", old_value, new_value)
VALUES ($1.id, $$update$$, $3, $1.' || ri.column_name || ', $2.' || ri.column_name || ');
END IF;'
USING NEW, OLD, ri.column_name;
END LOOP;
RETURN NEW;
END; $BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION fn_tasks_after_update()
OWNER TO postgres;
The trigger worked before adding the IF, and the syntax does not seem any different from what is in the 'INSERT INTO tasks_log' block.
This does work:
EXECUTE
'INSERT INTO tasks_log (task_id, type, "column", old_value, new_value)
VALUES ($1.id, $$update$$, $3, $1.' || ri.column_name || ', $2.' || ri.column_name || ');'
This does not work:
EXECUTE
'IF $1.' || ri.column_name || ' <> $2.' || ri.column_name || ' THEN
INSERT INTO tasks_log (task_id, type, "column", old_value, new_value)
VALUES ($1.id, $$update$$, $3, $1.' || ri.column_name || ', $2.' || ri.column_name || ');
END IF;'
What is going wrong?
Best Answer
This is the solution thanks to Abelisto's comment: