PostgreSQL
La base de données la plus sophistiquée au monde.

Ouverture de session

Navigation

Contactez-nous

Administration du site :
"equipe chez postgresqlfr point org"

Contact presse :
"fr chez postgresql point org"

Contact association :
"bureau chez postgresqlfr point org"

Questions PostgreSQL :
 IRC :
  serveur irc.freenode.net
  canal #postgresqlfr

Recherche

Accéder aux archives

« Octobre 2008  
Lun Mar Mer Jeu Ven Sam Dim
  2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31  

Syndication

Flux XML

Sondage

Quelle est la version de PostgreSQL la plus répandue sur vos serveurs ?
8.3
10%
8.2
42%
8.1
40%
8.0
2%
7.4
6%
7.3 ou antérieure
0%
Nombre de votes: 48

Horodater un enregistrement

Technique - général | Horodater un enregistrement

Par cioran le 12/09/2007 - 10:44

Bonjour,

Je suis novice en Postgre, j'espère que vous pourriez m'aider...

Chaque table de ma base de données a, entre autres, un champ lastModified; ce que je veux faire, c'est de mettre à jour ce champ à chaque insertion ou modification d'une ligne de la table; je pensais le faire avec la foncttion déclencheur et le déclencheur suivants :

CREATE OR REPLACE FUNCTION majdate()
RETURNS "trigger" AS
$BODY$
DECLARE

BEGIN
UPDATE utilisateur u
SET u.lastmodified = now()
WHERE u.loginu = new.loginu;
RETURN NEW;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION majdate() OWNER TO postgres;

CREATE TRIGGER triggermajdate
AFTER INSERT OR UPDATE
ON utilisateur
FOR EACH STATEMENT
EXECUTE PROCEDURE majdate();

Mais j'obtiens l'erreur suivante :
Record "new" is not assigned yet
The tuple structure of a not-yet-assigned record is indeterminate

Savez-vous pourquoi j'ai cette erreur?
En plus, je me pose des questions sur l'efficacité de mon trigger : son éxecution ne le redéclenche pas ? (trigger sur update, je fais un autre update dedans...)
Il y aura-t-il un meilleur moyen de garder la date de la dernière modification de la ligne?

Je vous remercie par avance de toute aide que vous pourriez m'aporter.

Options d'affichage des commentaires

Sélectionnez la méthode d'affichage des commentaires que vous préférez, puis cliquez sur "Sauvegarder les paramètres" pour activer vos changements.

Oui le code aurait du être

sparky/ = 12 Septembre, 2007 - 14:18

Oui le code aurait du être
CREATE OR REPLACE FUNCTION majdate()
RETURNS "trigger" AS
$BODY$
DECLARE

BEGIN
NEW.lastmodified := now();
RETURN NEW;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;


Je vois deux problèmes :

Guillaume Lelarge/ = 12 Septembre, 2007 - 14:21

Je vois deux problèmes :

1. trigger sur instruction... si l'UPDATE met à jour plusieurs lignes, comment le moteur peut-il savoir la ligne que vous souhaitez modifier ? il faut donc passer par un trigger en mode ligne (FOR EACH ROW) ;

2. vous exécutez un UPDATE sur un trigger INSERT/UPDATE --> récursivité assurée :) il faut donc modifier la ligne en cours de modification, d'où changer le trigger AFTER en trigger BEFORE et apporter la modification de la colonne avec l'opérateur d'affectation « := »

Cela devrait donner quelque chose comme cela (attention, non testé) :

CREATE OR REPLACE FUNCTION majdate()
RETURNS "trigger" AS
$BODY$
BEGIN
NEW.lastmodified := now();
RETURN NEW;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;

CREATE TRIGGER triggermajdate
BEFORE INSERT OR UPDATE
ON utilisateur
FOR EACH ROW
EXECUTE PROCEDURE majdate();

--
Guillaume Lelarge.
Administrateur de bases de données
http://dalibo.com - http://dalibo.org


Merci

cioran/ = 12 Septembre, 2007 - 15:44

Super !
Merci beaucoup à tous les deux, ça marche maintenant. En effet, j'oubliais l'affectation de type "Pascal" ... :) Et j'ai une idée plus claire maintenant sur les mots clés NEW, OLD, BEFORE, AFTER.
Encore merci pour votre réactivité.

A+
Claudiu


© PostgreSQLFr, tous droits réservés.
Site déclaré à la CNIL sous le numéro 1074678, conformément à la Loi en vigueur.