Thread: Stamping rows...

Stamping rows...

From
"Di Croce, Tony"
Date:
I am trying to find a way to stamp all of the rows affected by an update (or insert) with a unique value. For example, consider the following table:
 
create table people( name text, address text, city text, state text, zip text, phone text, change_number integer );
 
I would like the "change_number" column to hold the unique value.
 
I would like someone to be able to submit a query like this:
 
update people set name='tony', address='12345 A St', city='Downey', state='Ca', zip='92372', phone='864-0618' where zip='60612';
 
At this point, I want a couple things to happen:
 
1) Generate a unique "change_number" for this query. I can probably do this with a sequence.
2) As each row is updated (with the values the user specified in the update command), set it's "change_number" to be equal to the value generated in step 1.
 
At first I tried to do this as a trigger function. The problem with this solution is that if I dont have the function called for each row, I cannot modify those rows. if I DO have the function called for each row, how do they get the "change_number" they cannot simply call nextval() as it will be different for each row (they also couldn't call curval() because then who is ever calling nextval()?)
 
I also looked into rules, and but couldn't come up with a non recursive solution.
 
Any ideas?
 
    td
 

Re: Stamping rows...

From
Michael Fuhr
Date:
On Thu, Nov 18, 2004 at 04:23:50PM -0800, Di Croce, Tony wrote:
> I am trying to find a way to stamp all of the rows affected by an update (or
> insert) with a unique value.

[snip]

> At first I tried to do this as a trigger function. The problem with this
> solution is that if I dont have the function called for each row, I cannot
> modify those rows. if I DO have the function called for each row, how do
> they get the "change_number" they cannot simply call nextval() as it will be
> different for each row (they also couldn't call curval() because then who is
> ever calling nextval()?)

Have you tried calling nextval() in a FOR EACH STATEMENT trigger
and currval() in a FOR EACH ROW trigger?  This works for me in
simple tests.  I don't know if statement triggers are guaranteed
to fire before row triggers, but they do appear to work that way.

--
Michael Fuhr
http://www.fuhr.org/~mfuhr/

Re: Stamping rows...

From
"Greg Sabino Mullane"
Date:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


> I am trying to find a way to stamp all of the rows affected by
> an update (or insert) with a unique value. For example, consider
> the following table:
...
> At first I tried to do this as a trigger function.

You were on the right path:

ALTER TABLE people ADD mtime TIMESTAMPTZ NOT NULL DEFAULT now();

CREATE OR REPLACE FUNCTION update_mtime() RETURNS TRIGGER LANGUAGE PLPGSQL AS
'BEGIN NEW.mtime = now(); RETURN NEW; END;';

CREATE TRIGGER people_update_mtime BEFORE UPDATE ON people
FOR EACH ROW EXECUTE PROCEDURE update_mtime();

(I use a version of this for my incremental backup scheme)

Now every update (or insert) will cause all the rows changed to have the
same unique value. Unless you mess with your system clock. :) As a nice bonus,
you also get to see *when* each row was modified.

- --
Greg Sabino Mullane greg@turnstep.com
PGP Key: 0x14964AC8 200411222111

-----BEGIN PGP SIGNATURE-----

iD8DBQFBop11vJuQZxSWSsgRAuioAKDoVJjASMy0IYQ/T8mO76GEJKQdHQCg2KY7
13ul0+pLO+vEBEjGorUYiIA=
=rQnL
-----END PGP SIGNATURE-----



Re: Stamping rows...

From
Michael Fuhr
Date:
On Tue, Nov 23, 2004 at 02:14:52AM -0000, Greg Sabino Mullane wrote:

> CREATE OR REPLACE FUNCTION update_mtime() RETURNS TRIGGER LANGUAGE PLPGSQL AS
> 'BEGIN NEW.mtime = now(); RETURN NEW; END;';
>
> CREATE TRIGGER people_update_mtime BEFORE UPDATE ON people
> FOR EACH ROW EXECUTE PROCEDURE update_mtime();
>
> (I use a version of this for my incremental backup scheme)
>
> Now every update (or insert) will cause all the rows changed to have the
> same unique value.

Since now() doesn't advance during a transaction, every other update
or insert in the same transaction will get the same "unique" value
even if they were performed as separate statements; that may or may
not meet the requirements for uniqueness.  It also assumes that no
two transactions will ever start at exactly the same time.

--
Michael Fuhr
http://www.fuhr.org/~mfuhr/