How to pass a newly INSERTed row to a function?
-
01-03-2021 - |
Question
I have following tables:
table1: table2:
| uid | did | | uid | did |
|-----+-----| |-----+-----|
| 1 | 2 | | '1' | 2 |
| 4 | 2 | | '4' | 2 |
| 2 | 3 | | '2' | 3 |
| 1 | 8 | | '1' | 8 |
...
I need to create a trigger that would copy every inserted row from table1
to table2
, which is on a different schema.
So I made the following function:
CREATE OR REPLACE FUNCTION schema1."clone to table2"(uid numeric, did numeric)
RETURNS void
LANGUAGE sql
AS $function$
BEGIN;
INSERT INTO schema2."table2" ("uid", "did")
VALUES(uid::text, did);
END;
$function$
;
;
I have no clue how to pass this function properly to a trigger. After a bit of searching I found this:
CREATE TRIGGER on_insert
AFTER INSERT
ON schema1.table1
FOR EACH ROW
EXECUTE PROCEDURE schema1."clone to table2"(new."uid", new."did")
However it throws a "syntax error near ".", Position: 127"
. So I suppose I got it completely wrong.
I know views are perfect solution for my problem but I unfortunately can not use them in my scenario. I just need these two tables to be always identical, with a difference that table2
needs to have uid
as text
type.
Solution
A trigger requires a trigger function. And those can only be written in PL/pgSQL.
So you need something like this:
CREATE OR REPLACE FUNCTION schema1.clone_to_table2()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
BEGIN
INSERT INTO schema2."table2" ("uid, "did")
VALUES(new.uid::text, new.did);
return new;
END;
$function$
;
BEGIN
does not require a ;
at the end.
And then a trigger definition to go with that
CREATE TRIGGER on_insert
AFTER INSERT ON schema1.table1
FOR EACH ROW
EXECUTE PROCEDURE schema1.clone_to_table2();