Vous n'êtes pas identifié(e).

#1 29/09/2008 12:09:27

paftek
Membre

Colonne en lecture seule et TRIGGERS

Bonjour,

J'ai 2 tables, "commande" et "produit". Une commande est liée à 1..n produit(s).
J'ai ajouté une colonne "prix" à "commande", somme des prix des produits associés, calculé automatiquement par trigger.

Je souhaite maintenant que ce champ "prix" soit en lecture seule. J'ai donc ajouté un trigger sur la table "commande" pour empêcher tout UPDATE.
Le problème est que je souhaiterais quand même laisser passer l'UPDATE provenant du trigger sur la table "produit"...

Est-il possible de détecter l'origine d'un UPDATE et d'agir en conséquence ?

Merci,
Julien

Hors ligne

#2 29/09/2008 13:15:15

gleu
Administrateur

Re : Colonne en lecture seule et TRIGGERS

Je suppose donc que tu as un trigger en insert/update/delete sur la table produit pour calculer la somme qui sera mise à jour dans la table commande. Et tu veux ajouter un trigger pour empêcher la mise à jour de cette colonne dans la table commande. Ça ne marchera pas. Par contre, tu peux récupérer les update dans ton trigger et surcharger la valeur de la colonne prix par la somme de nouveau calculée des éléments de la commande.


Guillaume.

Hors ligne

#3 29/09/2008 15:20:41

paftek
Membre

Re : Colonne en lecture seule et TRIGGERS

OK merci. Voici un aperçu du code résultant :

Table commande

CREATE OR REPLACE FUNCTION commande_before_update() RETURNS TRIGGER AS $$
BEGIN
    IF OLD.price_ht <> NEW.price_ht OR OLD.price_ttc <> NEW.price_ttc
    THEN
        SELECT INTO NEW.price_ht, NEW.price_ttc
        COALESCE(sum(price_ht), 0) AS price_ht, COALESCE(sum(price_ttc), 0) AS price_ttc
        FROM produit WHERE commande_id = OLD.commande_id;
    END IF;
    
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Table Produit

CREATE OR REPLACE FUNCTION produit_after_update() RETURNS TRIGGER AS $$
BEGIN
    IF OLD.commande_id <> NEW.commande_id
    THEN
        UPDATE commande SET
            price_ht = price_ht - OLD.price_ht,
            price_ttc = price_ttc - OLD.price_ttc
        WHERE commande_id = OLD.commande_id;
        UPDATE commande SET
            price_ht = price_ht + NEW.price_ht,
            price_ttc = price_ttc + NEW.price_ttc
        WHERE commande_id = NEW.commande_id;
    ELSIF OLD.price_ht <> NEW.price_ht OR OLD.price_ttc <> NEW.price_ttc
    THEN
        UPDATE commande SET
            price_ht = price_ht - OLD.price_ht + NEW.price_ht,
            price_ttc = price_ttc - OLD.price_ttc + NEW.price_ttc
        WHERE commande_id = OLD.commande_id;
    END IF;
   
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Dernière modification par paftek (13/10/2008 18:19:46)

Hors ligne

#4 13/10/2008 09:03:52

SAS
Membre

Re : Colonne en lecture seule et TRIGGERS

Bonjour,

Le code présenté correspond-il à une solution fonctionnelle à votre problème ?


Stéphane Schildknecht
Conseil, formations et support PostgreSQL
http://www.loxodata.com

Hors ligne

#5 13/10/2008 10:11:48

paftek
Membre

Re : Colonne en lecture seule et TRIGGERS

Bonjour,

Cette solution fonctionne, mais je trouve peu élégant de surcharger les valeurs des colonnes price_ht et price_ttc de la table commande.

Mais bon, si c'est le seul moyen d'assurer la cohérence des données, et étant donné qu'il y aura très peu de mises à jour des prix sur ces tables, je pense que cette solution sera validée et exploitée très bientôt.

Hors ligne

Pied de page des forums