PL / pgSQL:如何使用IF NEW。<variable_column_name> <> OLD。<variable_column_name>

时间:2018-10-06 06:31:56

标签: postgresql stored-procedures plpgsql database-trigger

我对PL / pgSQL编程很陌生。我需要审核记录表中的更新列

create table sample_table(name varchar(15),city varchar(15),age int,mail varchar(20) primary key); 

审核表

create table sample_table__audits_dynamicols(mail varchar(20), columnchanged varchar(10), oldvalue varchar(10), changed_on timestamp(6) NOT NULL)

触发功能

CREATE FUNCTION public.log_sample_table_allchanges() RETURNS trigger AS $BODY$DECLARE
       _colname text;
       _tablename varchar(15) := 'sample_table';
       _schema varchar(15) := 'public';
       _changed_on time := now();
    BEGIN
      FOR _colname IN SELECT column_name FROM information_schema.Columns WHERE table_schema = _schema AND table_name = _tablename LOOP  
         IF NEW._colname <> OLD._colname THEN
            INSERT INTO sample_table__audits_dynamicols(mail,columnchanged, oldvalue ,changed_on)
            VALUES(OLD.mail,_colname,OLD.:_colname,_changed_on);
         END IF;
      END LOOP;
     RETURN NEW;
    END$BODY$
    LANGUAGE plpgsql VOLATILE NOT LEAKPROOF;

触发

create TRIGGER log_sample_table_allchanges
  BEFORE UPDATE
  ON SAMPLE_TABLE
  FOR EACH ROW
  EXECUTE PROCEDURE log_sample_table_allchanges();

要求:每当更改列值时,我都希望将其记录为

(邮件,列名,列值,日期)

例如:

insert into sample_table (name, mail, city, age) values('kanta','mk@foo.com','hyd',23);
insert into sample_table (name, mail, city, age) values('kmk','mk@gmail.com','hyd',23);

所以当我像下面这样更新时

update sample_table set age=24 where mail='mk@foo.com';
update sample_table set city='bza' where mail='mk@gmail.com'

我希望审核表记录类似

(mk@foo.com,age,23, timestamp) 
(mk@gmail.com, city, hyd, timestamp)

现在,我在触发器函数中遇到列比较问题。请帮助我纠正触发器功能以满足我的要求。

1 个答案:

答案 0 :(得分:0)

您可以使用invalidateFragmentMenus动态获取列的值并进行比较。

FragmentActivity

我不确定您为什么在审核表中将EXECUTE定义为CREATE OR REPLACE FUNCTION public.log_sample_table_allchanges() RETURNS trigger AS $BODY$ DECLARE _colname text; _tablename varchar(15) := 'sample_table'; _schema varchar(15) := 'public'; _changed_on timestamp := now(); _old_val text; _new_val text; BEGIN FOR _colname IN SELECT column_name FROM information_schema.Columns WHERE table_schema = _schema AND table_name = _tablename LOOP EXECUTE 'SELECT $1.' || _colname || ', $2.' || _colname USING OLD,NEW INTO _old_val, _new_val; --get the old and new values for the column. IF _new_val <> _old_val THEN INSERT INTO sample_table__audits_dynamicols(mail,columnchanged, oldvalue ,changed_on) VALUES(OLD.mail,_colname,_old_val,_changed_on); END IF; END LOOP; RETURN NEW; END$BODY$ LANGUAGE plpgsql VOLATILE NOT LEAKPROOF; ,如果同一封邮件更新两次,将导致mail违规。