Как создать триггер функцию аудита внутри хранимой процедуры? postgresql
Требуется создать хранимую процедуру, которая для каждой существующей таблицы в базе данных создаёт таблицу-двойника. Таблица-двойник имеет те же самые поля с теми же самыми типами + поле 'дата и время модификации' + поле 'пользователь, внёсший изменения' + поле 'тип модификации (вставка, удаление или изменение)'. Для каждой исходной таблицы добавить триггер, который после вставки, удаления или изменения данных добавляет соответствующую запись с новыми значениями в таблицу-двойник. Для итерирования по таблицам требуется использовать курсоры.
Хранимую процедуру сделал и вроде работает нормально, но триггер вставить в нее не получается, жалуется на неверный синтаксис:
CREATE OR REPLACE FUNCTION copy_table() RETURNS boolean language plpgsql as $$
DECLARE
cursor1 CURSOR FOR SELECT table_name from information_schema.tables WHERE table_schema = 'public';
cursor2 CURSOR (key text) FOR SELECT column_name, data_type from information_schema.columns WHERE
table_schema = 'public' and table_name = key ORDER BY ordinal_position;
tablename text;
tablename_new text;
columnname text;
data_type text;
newtrigger text;
BEGIN
OPEN cursor1;
LOOP
FETCH cursor1 INTO tablename;
tablename_new = tablename || '_copy';
IF NOT FOUND THEN EXIT;
END IF;
EXECUTE 'CREATE TABLE '||tablename_new||' ()';
OPEN cursor2(tablename);
LOOP
FETCH cursor2 INTO columnname, data_type;
IF NOT FOUND THEN EXIT;
END IF;
EXECUTE 'ALTER TABLE '||tablename_new||' ADD '||columnname||' '||data_type||'';
END LOOP;
CLOSE cursor2;
EXECUTE 'ALTER TABLE '||tablename_new||' ADD COLUMN operation text NOT NULL';
EXECUTE 'ALTER TABLE '||tablename_new||' ADD COLUMN stamp timestamp';
EXECUTE 'ALTER TABLE '||tablename_new||' ADD COLUMN userid text NOT NULL';
EXECUTE '
CREATE OR REPLACE FUNCTION audit() RETURNS TRIGGER as
$body1$
BEGIN
IF (TG_OP = 'DELETE') THEN
INSERT INTO public.'||tablename_new||' VALUES (OLD.*, TG_OP, now(), user);
ELSEIF (TG_OP = 'UPDATE') THEN
INSERT INTO public.'||tablename_new||' VALUES (NEW.*, TG_OP, now(), user);
ELSEIF (TG_OP = 'INSERT') THEN
INSERT INTO public.'||tablename_new||' VALUES (NEW.*, TG_OP, now(), user);
END IF;
END;
$body1$
language plpgsql;
CREATE TRIGGER audit_mod_table
AFTER INSERT OR UPDATE OR DELETE ON public.'||tablename||'
FOR EACH ROW EXECUTE FUNCTION audit();';
END LOOP;
CLOSE cursor1;
RETURN TRUE;
END; $$
Жалуется на синтаксис, здесь (конкретно на ' ' в 'DELETE', 'UPDATE', 'INSERT'), но без них триггер не работает и думает, что это столбцы:
IF (TG_OP = 'DELETE') THEN
INSERT INTO public.'||tablename_new||' VALUES (OLD.*, TG_OP, now(), user);
ELSEIF (TG_OP = 'UPDATE') THEN
INSERT INTO public.'||tablename_new||' VALUES (NEW.*, TG_OP, now(), user);
ELSEIF (TG_OP = 'INSERT') THEN
INSERT INTO public.'||tablename_new||' VALUES (NEW.*, TG_OP, now(), user);
END IF;