2

我有two tables

Table A
col1        col2         col3

Table B  
table_name        column_name        new_value     old_value

如果发生任何更新,table A它将插入数据table B

表 B 的输出是==>

    table_name         column_name         new_value             old_value
 ----------------     ------------------  --------------        -----------
      A                  {col1}   
      A                  {col1,col2}        {col1.new_value,      {col1.old_value,
                                             col2.new_value}       col2.old_value}, 

所以任何人都可以告诉我如何捕获 column_names 并将数据目标表存储为数组

4

2 回答 2

1

尝试这个

使用触发功能

    CREATE OR REPLACE FUNCTION update_history()
      RETURNS trigger AS
    $BODY$ 
     DECLARE col_name VARCHAR[]; 
     DECLARE od_value VARCHAR[]; 
     DECLARE ne_value VARCHAR[]; 
     DECLARE each_column RECORD; 
     DECLARE each_entity RECORD; 
     DECLARE column_name VARCHAR; 
     DECLARE old_value VARCHAR; 
     DECLARE new_value VARCHAR; 

     FOR each_column IN 
          select c.column_name  --- Get the all column names in affected table 
          from information_schema.columns c 
       where(table_name = tg_relname And c.TABLE_SCHEMA = TG_TABLE_SCHEMA)
           LOOP 
           FOR each_entity IN --- Its used to get old and new columns value 
       EXECUTE 'SELECT text((' || quote_literal(OLD.*) || '::"' || tg_table_schema || '"."' || tg_relname || '")."'  || each_column.column_name || '") as old_val, 
          text((' || quote_literal(NEW.*) || '::"' || tg_table_schema || '"."' || tg_relname || '")."'  || each_column.column_name || '") 
         AS new_val  
          FROM "' || tg_table_schema || '"."' || tg_relname || '";' 
          LOOP 
             old_value = each_entity.old_val; 
             new_value = each_entity.new_val; 
              IF old_value != new_value THEN 
              i=i+1; 
              col_name[i]=each_column.column_name; 
              od_value[i]=old_value; 
              ne_value[i]=new_value; 
              END IF; 
          END LOOP; 
          END LOOP; 

 INSERT INTO B  
            (   

              tablename,  
             columnnames,  
            oldvalues, 
 newvalues 
           )   
 VALUES 
         (   

            tg_relname,  
            col_name, 
             od_value, 
  ne_value
             ); 
        End if; 
      RETURN NEW; 
  END; 
  $BODY$
  LANGUAGE plpgsql VOLATILE
于 2013-09-19T05:02:34.157 回答
1

我认为使用PostgreSQL 的hstore 扩展是一个很好的例子:

create or replace function history_trigger_func()
returns trigger AS
$$
begin
    insert into TableB
    select
        tg_relname,
        case when tg_op in ('UPDATE', 'INSERT') then hstore(new) end,
        case when tg_op in ('UPDATE', 'DELETE') then hstore(old) end;

    return null;
end;
$$
language plpgsql;

create trigger tr_history_trigger after insert or update or delete on TableA
for each row execute procedure history_trigger_func();

sql fiddle demo

您可以通过删除未更改的列来进一步扩展此功能,或者,如果您使用的是 PostgreSQL 9.3,则可以使用JSON而不是 hstore。

于 2013-09-19T06:21:56.650 回答