Обсуждение: Function To Log Changes
Hi All, I have been tinkering with a function to log the changes made on
any column through a function and trigger. However, I cant think of a way
to make this work through pl/pgsql. Any one have any ideas, or is it just
not possible?
SNIP
create or replace function logchange2() returns OPAQUE as '
DECLARE columnname record; c2 VARCHAR(64);
BEGIN
/* Cycle through the column names so we can find the changes being made */
FOR columnname IN SELECT attname FROM pg_attribute, pg_type WHERE attnum > 0 AND typrelid=attrelid AND
typname=''SOMETABLE''LOOP
c2 := CAST(columnname.attname AS VARCHAR(64));
/* here lies the problem. How would I make plpgsql see OLD.columnname in
a dynamic fashion. I know this wont work whats below, but I am just
trying to express what I am trying to do */ IF ''OLD.'' || c2 != ''NEW.'' || c2 THEN /* IF CHANGED
DOSOMETHING */ RAISE NOTICE ''Update on column %'', c2; END IF;
END LOOP;
return NULL;
END;
'
LANGUAGE plpgsql;
create trigger logchange2 AFTER UPDATE on TABLENAME FOR EACH ROW EXECUTE
PROCEDURE logchange2();
Gavin, > Hi All, I have been tinkering with a function to log the changes made on > any column through a function and trigger. However, I cant think of a way > to make this work through pl/pgsql. Any one have any ideas, or is it just > not possible? It could be done, but would be extremely slow and awkward using current PL/ pgsql syntax. You'd have to query the system tables for a list of columns, and then execute a series of dynamic queries. I recommend instead one of the following two approaches: 1) Simply log the whole row of each archived table and don't worry about logging the individual columns, or 2) Use PL/tcl, PL/Pyton, or C where you can select columnns by ordinal position or other dynamic factor. -- -Josh BerkusAglio Database SolutionsSan Francisco
"Gavin" <gavin@grabias.com> writes:
> Hi All, I have been tinkering with a function to log the changes made on
> any column through a function and trigger. However, I cant think of a way
> to make this work through pl/pgsql.
plpgsql won't do it, but you could do it in pltcl, I believe.
Or resort to C ;-)
regards, tom lane
A plpython solution is available in Issue #66 of PostgreSQL GeneralBits. http://www.varlena.com/GeneralBits/66 Let me know if this helps. elein On Mon, Apr 05, 2004 at 01:01:39PM -0400, Gavin wrote: > Hi All, I have been tinkering with a function to log the changes made on > any column through a function and trigger. However, I cant think of a way > to make this work through pl/pgsql. Any one have any ideas, or is it just > not possible? > > SNIP > create or replace function logchange2() returns OPAQUE as ' > DECLARE > columnname record; > c2 VARCHAR(64); > > BEGIN > > /* Cycle through the column names so we can find the changes being made */ > FOR columnname IN SELECT attname FROM pg_attribute, pg_type > WHERE attnum > 0 AND typrelid=attrelid AND typname=''SOMETABLE'' LOOP > > c2 := CAST(columnname.attname AS VARCHAR(64)); > /* here lies the problem. How would I make plpgsql see OLD.columnname in > a dynamic fashion. I know this wont work whats below, but I am just > trying to express what I am trying to do */ > IF ''OLD.'' || c2 != ''NEW.'' || c2 THEN > /* IF CHANGED DO SOMETHING */ > RAISE NOTICE ''Update on column %'', c2; > END IF; > > END LOOP; > > return NULL; > END; > ' > LANGUAGE plpgsql; > > create trigger logchange2 AFTER UPDATE on TABLENAME FOR EACH ROW EXECUTE > PROCEDURE logchange2(); > > > ---------------------------(end of broadcast)--------------------------- > TIP 7: don't forget to increase your free space map settings
On Mon, 5 Apr 2004 13:01:39 -0400 (EDT) "Gavin" <gavin@grabias.com> wrote: > Hi All, I have been tinkering with a function to log the changes made on > any column through a function and trigger. However, I cant think of a way > to make this work through pl/pgsql. Any one have any ideas, or is it just > not possible? http://gborg.postgresql.org/project/tablelog/projdisplay.php is this what you are looking for? cu erik -- Erik Thiele