Re: [SQL] Triggers, plpgsql, etc.

From: jwieck(at)debis(dot)com (Jan Wieck)
To: labouiss(at)club-internet(dot)fr (Christophe Labouisse)
Cc: pgsql-sql(at)postgreSQL(dot)org
Subject: Re: [SQL] Triggers, plpgsql, etc.
Date: 1999-01-15 17:36:15
Message-ID: m101DAO-000EBQC@orion.SAPserv.Hamburg.dsh.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-sql

Christophe Labouisse wrote:

>
> I want to have a =AB date of the last update =BB field in a table. So I
> create a table with datetime field (liens_maj) and a default value to
> 'now'.
>
> As shown below it works fine.
>
> lumiere=3D> insert into liens (liens_nom,liens_url) values ('Ga','GAbuzo'=
> );
> INSERT 1009600 1
> lumiere=3D> select * from liens;
> liens_id|liens_nom|liens_url|liens_commentaire|liens_maj
> --------+---------+---------+-----------------+--------------------------=
> --
> 1|Ga |GAbuzo | |Thu Jan 14 13:29:35 1999 C=
> ET
> (1 row)
>
>
> To update automatically this field when the row is updated I thought
> of a trigger calling a plpgsql function :

Good idea! Maybe you want to force the initial value to the
actual time too, so it will allways be the time of the insert
and not only the fallback 'default' and the user isn't able
to insert anything else.

Also the job of a trigger.

>
> create trigger liens_maj_trig after update
> on liens for each row execute procedure liens_maj_fun();
>
>
> create function liens_maj_fun () returns opaque as '
> begin
> update liens set liens_maj=3D''now'' where liens_id=3Dold.liens_id;
> return new;
> end;
> ' language 'plpgsql';
>
> When I try to update a record I get the following error :
>
> lumiere=3D> update liens set liens_nom=3D'zzz' where liens_id=3D1;
> ERROR: There is no operator '=3D$' for types 'int4' and 'int4'
> You will either have to retype this query using an explicit cast,
> or you will have to define the operator using CREATE OPERATOR

Lucky you :-)

I expected a final crash of the backend in this case (and got
it on test), because the trigger procedure itself does
exactly the operation that triggers it. This is an endless
recursion!

The following is the right solution:

CREATE FUNCTION liens_maj_fun() RETURNS opaque AS '
BEGIN
new.liens_maj := ''now'';
RETURN new;
END;
' LANGUAGE 'plpgsql';

CREATE TRIGGER liens_maj_trig BEFORE [INSERT OR] UPDATE TO liens
FOR EACH ROW EXECUTE PROCEDURE liens_maj_fun();

Why? A trigger procedure that is fired BEFORE can replace
values in NEW just before it is put into the database.

Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me. #
#======================================== jwieck(at)debis(dot)com (Jan Wieck) #

In response to

Browse pgsql-sql by date

  From Date Subject
Next Message Gene Selkov Jr. 1999-01-15 19:39:16 Re: [SQL] Text type
Previous Message Christophe Labouisse 1999-01-15 12:10:58 Triggers, plpgsql, etc.