Thread: Help with function

Help with function

From
"Chris Hoover"
Date:
I am trying to write a very generic function to be used for table auditing.  I am kind of stuck on how to make the
functionuse the column names I pull from the db.  Is there anyway to do what I have below?  My main concern is this
segment:

if (new.columnName != old.columnName or
        (old.columnName is null and new.columnName is not null) or
        (old.columnName is not null and new.columnName is null)
       ) then

How can I get PostgreSQL to substitute the selected column name for the old.columnName/new.columnName?

Thanks,

Chris

CREATE OR REPLACE FUNCTION table_update_trig_func() RETURNS "trigger" AS
'
declare
/* setup the local variables */
  loopRec record;
  columnName varchar;
  sqlStr varchar(2000);
begin
  /* write out to the log file where we are */
  raise notice \'in start of table_update_trig_func\';

  /* setup the current sql string */
  sqlStr := \'select attname as columnName \';
  sqlStr := sqlStr || \'from pg_class, pg_attribute, pg_type \';
  sqlStr := sqlStr || \'where pg_class.relname = \'\'table\'\' \';
  sqlStr := sqlStr || \'and pg_attribute.attrelid = pg_class.oid \';
  sqlStr := sqlStr || \'and pg_attribute.atttypid = pg_type.oid \';
  sqlStr := sqlStr || \'and pg_type.typname not in (\'\'oid\'\',\'\'tid\'\',\'\'xid\'\',\'\'cid\'\',\'\'oidvector\'\')
\';
  sqlstr := sqlStr || \'order by attname \';

  /* start the check of each column in the table */
  for loopRec in execute sqlStr loop

    raise notice \'value of loopRec.columnName is %\', loopRec.columnName;

    columnName := loopRec.columnName;

    if (new.columnName != old.columnName or
        (old.columnName is null and new.columnName is not null) or
        (old.columnName is not null and new.columnName is null)
       ) then

      raise notice \'table_update_trig_func - calling insert_into_log function\';

      select * from eedi.insert_into_clmchglog(<parameters>);

    end if;

  end loop;

  return new;

end;
'
LANGUAGE 'plpgsql' STABLE SECURITY DEFINER;



Re: Help with function

From
Alvaro Herrera
Date:
On Thu, Jun 09, 2005 at 06:17:24PM +0000, Chris Hoover wrote:
> I am trying to write a very generic function to be used for table auditing.  I am kind of stuck on how to make the
functionuse the column names I pull from the db.  Is there anyway to do what I have below?  My main concern is this
segment:
>
> if (new.columnName != old.columnName or
>         (old.columnName is null and new.columnName is not null) or
>         (old.columnName is not null and new.columnName is null)
>        ) then
>
> How can I get PostgreSQL to substitute the selected column name for the old.columnName/new.columnName?

Standard answer has been "can't do that in plpgsql".  You may want to
try pl/perl, pl/python (does that support triggers?) or pl/tcl.

If performance is an issue, write the function in C.

--
Alvaro Herrera (<alvherre[a]surnet.cl>)
"If it wasn't for my companion, I believe I'd be having
the time of my life"  (John Dunbar)