2017-06-26 2 views
2

私はいくつかのテーブルを持っています。 私はテーブルを持っている 履歴テーブルにコピー・ロー上のuniverstal Postgresの関数を書きたい:Postgresはすべてのテーブルにユニバーサル関数を作成します

table1 
table1_h 

table2 
table2_h 

私は

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; 

や関数の作成でしたが、アップデートがエラーになった後(ヘルプstackoverflowので)関数を書きました。

ERROR: syntax error at or near "," 
ROW 1: ...RT INTO table1_h VALUES ((12,,,0,,"Anto... 

エラーは、この挿入である場合、私は知っているが、私はそれを修復する方法がわかりません。 構造テーブルtable1とtable1_hは同じですが、table1_hにもう1つのカラム(id_h)があります

psql関数の作成方法を教えてください。

Thnak you。

答えて

1

テーブル1からテーブル1_hに '古い'値を挿入すると仮定します。

追加の列が問題です。列に名前を付けることなく挿入物を使用するときは、挿入に一致する番号とタイプを使用する必要があります。

カラム参照を使用する必要があります。

例えば、

Insert into table1_h(column1, column2, column3) 
values (a,b,c) 

表table1_hの追加列のデフォルト値を検討してください。

+0

はい、あなたの答えをありがとうございました。 Abelistoは普遍的な挿入をtable_hに書き込みます。それは働いている。 – ondrusu

4
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; 

dbfiddle

更新それはあなたの問題を解決し、私はあなたがあなたの履歴テーブル内のビットの詳細情報を持っているしたいと思います。これは、もう少し複雑になります。

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; 

dbfiddle

+0

はい、動作しています。どうもありがとうございました。よくやった。 :) – ondrusu