Postgres создает универсальную функцию на весь стол
У меня есть несколько таблиц БД. Я хочу написать универсальную функцию postgres для копирования строк в таблицы истории У меня есть таблицы:
table1
table1_h
table2
table2_h
Я написал функцию (с помощью stackru)
CREATE OR REPLACE FUNCTION copy_history_f() RETURNS TRIGGER AS
$BODY$
DECLARE
tablename_h text:= TG_TABLE_NAME || '_h';
BEGIN
EXECUTE 'INSERT INTO ' || quote_ident(TG_TABLE_SCHEMA) || '.' || quote_ident(tablename_h) || ' VALUES (' || OLD.* ||')';
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
И функции создаются, но после обновления есть ошибка.
ERROR: syntax error at or near ","
ROW 1: ...RT INTO table1_h VALUES ((12,,,0,,"Anto...
Я знаю, где ошибка в этой вставке, но я не знаю, как это исправить. Структурные таблицы table1 и table1_h идентичны, но у table1_h есть еще один столбец (id_h)
Можете ли вы помочь мне, как я могу создать функцию PSQL?
Спасибо тебе.
2 ответа
drop table if exists t;
drop table if exists t_h;
drop function if exists ftg();
create table t(i serial, x numeric);
insert into t(x) values(1.1),(2.2);
create table t_h(i int, x numeric);
create function ftg() returns trigger language plpgsql as $ftg$
declare
tablename_h text:= TG_TABLE_NAME || '_h';
begin
execute format($q$ insert into %I.%I select $1.*; $q$, TG_TABLE_SCHEMA, tablename_h) using old;
return null;
end $ftg$;
create trigger tg_t after delete on t for each row execute procedure ftg();
delete from t where i = 1;
select * from t_h;
Обновление Это решает вашу проблему, но я думаю, что вы хотите иметь немного больше информации в ваших таблицах истории. Это будет немного сложнее:
drop table if exists t;
drop table if exists t_h;
drop function if exists ftg();
create table t(i serial, x numeric);
insert into t(x) values(1.1),(2.2);
create table t_h(
hi serial, -- just ID
hd timestamp, -- timestamp
hu text, -- user who made changes
ha text, -- action
i int, x numeric
);
create function ftg() returns trigger language plpgsql as $ftg$
declare
tablename_h text:= TG_TABLE_NAME || '_h';
begin
execute format(
$q$
insert into %I.%I
select
nextval(%L || '_hi_seq'),
clock_timestamp(),
current_user,
%L,
$1.*
$q$, TG_TABLE_SCHEMA, tablename_h, tablename_h, TG_OP) using old;
return null;
end $ftg$;
create trigger tg_t after delete or update on t for each row execute procedure ftg();
update t set x = x * 2;
update t set x = x * 2 where i = 2;
delete from t where i = 1;
select * from t_h;
Я предполагаю, что вы вставляете "старые" значения из table1 в table1_h.
Дополнительный столбец - ваша проблема. Когда вы используете вставку без именования столбцов, вы должны использовать соответствующий номер и тип для вставки.
Вы должны использовать ссылки на столбцы.
например.
Insert into table1_h(column1, column2, column3)
values (a,b,c)
Рассмотрим значение по умолчанию для дополнительного столбца в таблице table1_h.