Précédent   Forum des professionnels en informatique > Bases de données > PostgreSQL
PostgreSQL Forum PostgreSQL. Avant de poster -> F.A.Q PostGreSQL Tutoriels PostGreSQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 30/09/2005, 12h53   #1
Membre éclairé
 
Inscription : janvier 2004
Messages : 426
Détails du profil
Informations personnelles :
Âge : 39
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : janvier 2004
Messages : 426
Points : 311
Points : 311
Par défaut Création de mon premier trigger : Argh !

Bonjour,

J'essaye de créer mon premier trigger et je m'arrache un peu les cheveux..

J'ai essayé avec phpPgAdmin et directement en ligne de commande avec psql.. mais il ne veut rien savoir..

Bon, j'ai une table "dossiers" et une "ligne_facture" dans un schema "clients_dossiers"

L'idee du trigger est tres simple.. a chaque insertion, (et dans l'ideal pour la suite, pour chaque update ou delete aussi...), je veux mettre a jour le champ "total" dans la table "dossiers" avec le montant declare dans "ligne_facture"..

Le 1er argument est le montant unitaire, le 2eme, le nombre et le 3e, l'id dossier..

Donc :

CREATE FUNCTION calcul_total (numeric, integer, integer) RETURNS OPAQUE AS '
BEGIN
UPDATE dossiers SET total=total+($1*$2) WHERE id_dossier=$3;
END;
' LANGUAGE plpgsl;

la, il me sort
"CREATE FUNCTION" donc ca a du marcher ?

Apres je cree mon trigger :
CREATE TRIGGER trg_calcul_total AFTER INSERT ON ligne_facture FOR EACH ROW EXECUTE PROCEDURE calcul_total(montant_unitaire,nb,id_dossier);

Et la, j'ai deux fois la meme erreur d'affichée :
ERROR : function calcul_total() does not exists


Et en passant par phpPgAdmin.. pas mieux !

Alors comment faire ?

Et autre question, pendant que j'y suis.. quand j'appelle la fonction depuis un trigger, je peux passer les parametres comme je l'ai fait ci dessus, en nommant les colonnes a utiliser ?

Merci de m'aider.. je suis un peu paumé.. j'ai toujours bossé avec mysql.. et ca n'a rien a voir.. ou presque !
zevince est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/09/2005, 14h18   #2
Expert Confirmé Sénior
 
Avatar de GrandFather
 
Inscription : mai 2004
Messages : 4 490
Détails du profil
Informations personnelles :
Âge : 42

Informations forums :
Inscription : mai 2004
Messages : 4 490
Points : 5 049
Points : 5 049
Par défaut Re: Création de mon premier trigger : Argh !

Citation:
Envoyé par zevince
Merci de m'aider.. je suis un peu paumé.. j'ai toujours bossé avec mysql.. et ca n'a rien a voir.. ou presque !
Non, effectivement.

Les fonctions destinées à servir pour un trigger doivent répondre à plusieurs critères :
  • Le type de la variable retournée doit être TRIGGER
  • Elles ne prennent aucun arguments
  • Dans le cas d'un trigger BEFORE, la fonction doit retourner dans la variable NEW l'enregistrement qui sera effectivement utilisé pour mouvementer la table (ou NULL dans le cas d'une annulation)
Dans le corps de la fonction, on peut accéder aux champs de la table à laquelle est relié le trigger, ainsi qu'à des variables de contexte par des variables spéciales : NEW, OLD, TG_WHEN...

Dans ton cas, le code sera le suivant :

Code :
1
2
3
4
5
6
7
8
CREATE OR REPLACE FUNCTION calcul_total() RETURNS TRIGGER AS '
BEGIN
  UPDATE dossiers SET total = total + NEW.montant_unitaire * NEW.nb WHERE id_dossier = NEW.id_dossier;
  RETURN NEW;
END;
' LANGUAGE plpgsql; 
 
CREATE TRIGGER tg_calcul_total AFTER INSERT ON ligne_facture FOR EACH ROW EXECUTE PROCEDURE calcul_total();
__________________
FAQ XML
------------
« Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
Giacomo Leopardi
GrandFather est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/09/2005, 15h21   #3
Membre éclairé
 
Inscription : janvier 2004
Messages : 426
Détails du profil
Informations personnelles :
Âge : 39
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : janvier 2004
Messages : 426
Points : 311
Points : 311
AAaaaaahhhh fabuleux ! ca marche ! :-)
Merci !!
j'avais lu la doc, mais les triggers en C.. ca a l'air bien compliqué !
Et la doc est pas super claire !
et y'a moyen de gerer les cas UPDATE et DELETE dans la meme fonction ou vaut mieux faire un trigger different pour chaque cas ?
zevince est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/09/2005, 17h04   #4
Expert Confirmé Sénior
 
Avatar de GrandFather
 
Inscription : mai 2004
Messages : 4 490
Détails du profil
Informations personnelles :
Âge : 42

Informations forums :
Inscription : mai 2004
Messages : 4 490
Points : 5 049
Points : 5 049
Citation:
Envoyé par zevince
j'avais lu la doc, mais les triggers en C.. ca a l'air bien compliqué !
Pourquoi veux-tu faire tes triggers en C, si le PLPGSQL suffit ?
Citation:
Envoyé par zevince
et y'a moyen de gerer les cas UPDATE et DELETE dans la meme fonction ou vaut mieux faire un trigger different pour chaque cas ?
Là, il y a deux écoles. Dans le premier cas, tu n'as qu'une fonction à écrire mais son code sera un peu plus compliqué (il faudra utiliser la variable TG_OP pour identifier l'opération sur la table) que celui des fonctions du deuxième. Personnellement, j'aurais plutôt une préférence pour la première méthode...
__________________
FAQ XML
------------
« Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
Giacomo Leopardi
GrandFather est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/09/2005, 17h11   #5
Membre éclairé
 
Inscription : janvier 2004
Messages : 426
Détails du profil
Informations personnelles :
Âge : 39
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : janvier 2004
Messages : 426
Points : 311
Points : 311
Citation:
Envoyé par GrandFather
Pourquoi veux-tu faire tes triggers en C, si le PLPGSQL suffit ?
Tout simplement parce que la doc ne donne un exemple QUE en C ..
http://www.postgresql.org/docs/8.0/s...r-example.html

heureusement, on trouve des docs sur plpgsql un peu partout..

Bon sinon j'ai traité les cas update et delete avec un trigger pour chaque.. et ca marche super bien.. apres avoir fait tout ca en php/mysql et en basculant sur php/postgres, on se sent tout d'un coup bien soulagé ...

Merci pour ton aide !
zevince est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/03/2006, 12h22   #6
Candidat au titre de Membre du Club
 
Inscription : avril 2004
Messages : 16
Détails du profil
Informations forums :
Inscription : avril 2004
Messages : 16
Points : 11
Points : 11
Bonjour,
je viens de réussir mon premier trigger.
Very Happy
Le but étant d'enregistrer les modif sur une table, en gardant l'ancienne valeur, la nouvelle, et la date et heure de la modif.
voici la fonction:

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

DECLARE
action_effectuee text;
valeur_initiale text;
valeur_modifiee text;
BEGIN
action_effectuee := TG_OP ;
SELECT INTO valeur_initiale OLD.lbaction FROM actions ;
SELECT INTO valeur_modifiee NEW.lbaction FROM actions ;

INSERT INTO audit values
(now(), action_effectuee, valeur_initiale, valeur_modifiee);
RETURN NEW;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION proc_update_actions() OWNER TO postgres;

ça fonctionne très bien en update, mais pas en delete (à cause du NEW.lbaction qui est inconnu en cas de delete, je suppose).
Comment étoffer cette fonction pour qu'elle gère l'update et le delete ?
Merci
jacques trepp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/03/2006, 11h34   #7
Candidat au titre de Membre du Club
 
Inscription : avril 2004
Messages : 16
Détails du profil
Informations forums :
Inscription : avril 2004
Messages : 16
Points : 11
Points : 11
Bonjour,
je m'auto-répond :
CREATE OR REPLACE FUNCTION proc_update_actions()
RETURNS "trigger" AS
$BODY$

DECLARE

action_effectuee text;
valeur_initiale text;
valeur_modifiee text;

BEGIN

action_effectuee := TG_OP ;
IF action_effectuee = 'DELETE' THEN
SELECT INTO valeur_initiale OLD.lbaction FROM actions ;
INSERT INTO audit values
(now(), action_effectuee, valeur_initiale, NULL);
RETURN OLD;
ELSE
SELECT INTO valeur_initiale OLD.lbaction FROM actions ;
SELECT INTO valeur_modifiee NEW.lbaction FROM actions ;
INSERT INTO audit values
(now(), action_effectuee, valeur_initiale, valeur_modifiee);
RETURN NEW;
END IF;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION proc_update_actions() OWNER TO postgres;
jacques trepp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/03/2006, 11h52   #8
Candidat au titre de Membre du Club
 
Inscription : avril 2004
Messages : 16
Détails du profil
Informations forums :
Inscription : avril 2004
Messages : 16
Points : 11
Points : 11
Concernant cette fonction, j'aimerais bien ajouter dans mon fichier audit, soit l'identifiant, soit le nom de l'utilisateur qui a effectué l'update ou le delete.

y a-t-il une variable pour identifier l'utilisateur ?

Merci d'avance.
jacques trepp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/04/2006, 12h03   #9
Invité régulier
 
Inscription : février 2006
Messages : 9
Détails du profil
Informations forums :
Inscription : février 2006
Messages : 9
Points : 7
Points : 7
Concernant ton utilisateur, tu as la variable current_user qui contient l'information que tu cherches.
cedricbr est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 20h21.


 
 
 
 
Partenaires

Hébergement Web