Re: [SQL] Triggers, plpgsql, etc.
От | jwieck@debis.com (Jan Wieck) |
---|---|
Тема | Re: [SQL] Triggers, plpgsql, etc. |
Дата | |
Msg-id | m101DAO-000EBQC@orion.SAPserv.Hamburg.dsh.de обсуждение исходный текст |
Ответ на | Triggers, plpgsql, etc. (Christophe Labouisse <labouiss@club-internet.fr>) |
Список | 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@debis.com (Jan Wieck) #
В списке pgsql-sql по дате отправления: