Postgresql – How to pass a newly INSERTed row to a function

functionspostgresqltrigger

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.

Best Answer

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();