I have tables that have almost the same columns. The first table has the current values and the other table has the old values and an additional column to store the date data is inserted. The second table is named as the first table with the prefix _bit. Example:
CREATE TABLE x (
id serial PRIMARY KEY,
f1 integer NOT NULL,
f2 character varying(10) NOT NULL,
cuando timestamp without time zone NOT NULL DEFAULT now()
);
CREATE TABLE _bitx (
id integer,
f1 integer,
f2 character varying(10),
cuando timestamp without time zone,
cuandobit timestamp without time zone DEFAULT now()
);
I have a trigger function that copies the OLD
values of a table to another:
CREATE FUNCTION bitacoratabla() RETURNS trigger AS $$
BEGIN
INSERT INTO _bitx VALUES((OLD).*);
RETURN NEW;
END;
$$ LANGUAGE plpgsql
The trigger:
CREATE TRIGGER trigbitx
BEFORE UPDATE
ON public.x
FOR EACH ROW
EXECUTE PROCEDURE public.bitacoratabla();
All this works fine but I must do this for multiple tables that follow the same rules.
I modified the function in order to create the name of the table where I will insert data but I am having problems with that and with (OLD).*
CREATE FUNCTION bitacoratabla() RETURNS trigger AS $$
DECLARE
tabla text := '_bit' || quote_ident(TG_TABLE_NAME);
BEGIN
EXECUTE 'INSERT INTO ' || tabla || ' VALUES(' || (OLD).* || ')';
RETURN NEW;
END;
$$ LANGUAGE plpgsql
I am new to PL/pgSQL and thought I did not have to do more. Any ideas?
UPDATE
As all you suggest it is better to use format()
and pass values with USING
keyword. Thank you. This is what I did:
CREATE OR REPLACE FUNCTION bitacoratabla() RETURNS TRIGGER
AS $$
BEGIN
EXECUTE format('INSERT INTO %I SELECT $1.*', '_bit' || TG_TABLE_NAME) USING OLD;
RETURN NEW;
END
$$ LANGUAGE PLPGSQL;