Как создать триггер функцию аудита внутри хранимой процедуры? 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;

Ответы (0 шт):