Vous n'êtes pas identifié(e).
Pages : 1
PostgreSQL 8.4 - Debian - OOo Base 3 - PgAdmin 3
Bonjour à tous,
Je développe ma BDD pour ma société et actuellement j'en suis à la facturaton.
Actuellement, elle compte à peu près 12-13 tables différentes (fournisseurs, stocks...).
Mon ennui actuellement, c'est que j'ai besoin de réaliser les champs pour la facturation.
Pour la présentation j'ai OOo Base. Je les fais déjà fonctionner ensemble, tout va bien. Je ne veux pas de log externe (FactOoor..).
J'ai reproduit ci-dessous un exemple de ce que je veux (attention, cette table ne comporte qu'un champ mais j'ai besoin de la logique):
Table 1
-- Table: "Calculs"."Champs"
-- DROP TABLE "Calculs"."Champs";
CREATE TABLE "Calculs"."Champs"
(
"Champ 1" numeric,
"Id_Opération" integer NOT NULL,
CONSTRAINT "Champs_pkey" PRIMARY KEY ("Id_Opération")
)
WITH (
OIDS=FALSE
);
ALTER TABLE "Calculs"."Champs" OWNER TO postgres;
Puis la table de résultat:
-- Table: "Calculs"."Résultat"
-- DROP TABLE "Calculs"."Résultat";
CREATE TABLE "Calculs"."Résultat"
(
resultat numeric
)
WITH (
OIDS=FALSE
);
ALTER TABLE "Calculs"."Résultat" OWNER TO postgres;
Ce que je souhaite:
Que la table Résultat calcule toutes les lignes du champs 1. Résultat correspond en vrai au Total à payer.
Pourtant je parviens à effectuer des triggers mais que sur une ligne.
Sur plusieurs lignes voire plusieurs tables, je suis perdu.
Mais j'ai envie d'apprendre.
Pouvez-vous m'aider, svp?
LeHibou
Dernière modification par LeHibou (17/06/2010 16:07:45)
Hors ligne
Bonjour,
Pourrais tu reformuler la question ? Une table ne calcule pas, c'est juste un moyen de stockage. Calculer quoi sur champ1 ?
Marc.
Hors ligne
Bien sûr, au temps pour moi, je me suis mal exprimé.
Voici le schéma ci dessous qui représente la situation:
Table 1
Id Produit
Prix unitaire
Quantité
Remise
Prix net HT
Taux Tva
Tva totale
La table 2, quant à elle, permet de calculer le total à payer.
Total HT
Total TTC
Bien sûr, la présentation, ni toutes les fonctionnalités ne sont pas là mais au moins, c'est plus simple.
J'ai été piégé car je ne peux pas mettre de trigger dans la même table. en effet, il ne me permet d'avoir que les résultats sur la ligne (à mon niveau de connaissance!).
Il faudrait que je puisse avoir les totaux pour préparer mes facturations. Sachant que ce que j'attends de postgresql, ce ne sont que les calculs, la présentation, je la fais dans un formulaire OOo Base.
Ce que je veux est possible ou pas? Sinon je passe sous OOo Calc pour mes factures et serai obligé de maintenir à jour ma base manuellement... Pas top.
Dernière modification par LeHibou (17/06/2010 16:49:58)
Hors ligne
Si je comprends bien, ce que vous voulez, c'est un trigger sur la table 1 qui maintienne les totaux de la table 2 à jour ?
Marc.
Hors ligne
Tout à fait!
Hors ligne
Voici un exemple de code qui ferait ce genre de travail.
marc=# CREATE TABLE detail (commande int, montant numeric);
CREATE TABLE
marc=# CREATE TABLE somme (commande int, somme numeric);
CREATE TABLE
CREATE OR REPLACE FUNCTION calc_somme () RETURNS trigger as $code$
BEGIN
IF (TG_OP = 'DELETE') THEN
UPDATE somme SET somme=somme-OLD.montant WHERE commande=OLD.commande; -- Aucune importance si l'enregistrement n'existe pas
RETURN OLD;
ELSIF (TG_OP = 'UPDATE') THEN
UPDATE somme SET somme=somme-old.montant+new.montant WHERE commande=new.commande;
IF NOT FOUND THEN
INSERT INTO somme (commande,somme) VALUES (NEW.commande,NEW.montant);
END IF;
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
UPDATE somme SET somme=somme+NEW.montant WHERE commande=NEW.commande;
if NOT FOUND THEN
INSERT INTO somme (commande,somme) VALUES (NEW.commande,NEW.montant);
END IF;
RETURN NEW;
END IF;
RETURN NEW;
END;
$code$ LANGUAGE plpgsql;
CREATE TRIGGER maj_somme AFTER INSERT OR UPDATE OR DELETE ON detail FOR EACH ROW EXECUTE PROCEDURE calc_somme();
Marc.
Hors ligne
Merci Marc,
J'ai tenté, j'ai échoué.
Le problème, c'est je tente de personnaliser le code suivant la structure schéma.table ou table.colonne mais je m'y perd dans la dénomination -identique- du nom de la table et du nom de la colonne "somme".
C'est à dire que je tente de comprendre mais ne suis pas sûr de ce à quoi fait référence somme dans un cas et somme dans l'autre.
J'attends vos précisions? merci d'avance en tout cas, je n'aurais jamais trouvé ce code.
Hors ligne
Ah oui, ok. Je la refais en remplacant ça.
marc=# CREATE TABLE detail (commande int, montant numeric);
CREATE TABLE
marc=# CREATE TABLE facture (commande int, somme numeric);
CREATE TABLE
CREATE OR REPLACE FUNCTION calc_somme () RETURNS trigger as $code$
BEGIN
IF (TG_OP = 'DELETE') THEN
UPDATE facture SET somme=somme-OLD.montant WHERE commande=OLD.commande; -- Aucune importance si l'enregistrement n'existe pas
RETURN OLD;
ELSIF (TG_OP = 'UPDATE') THEN
UPDATE facture SET somme=somme-old.montant+new.montant WHERE commande=new.commande;
IF NOT FOUND THEN
INSERT INTO facture (commande,somme) VALUES (NEW.commande,NEW.montant);
END IF;
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
UPDATE facture SET somme=somme+NEW.montant WHERE commande=NEW.commande;
if NOT FOUND THEN
INSERT INTO facture (commande,somme) VALUES (NEW.commande,NEW.montant);
END IF;
RETURN NEW;
END IF;
RETURN NEW;
END;
$code$ LANGUAGE plpgsql;
CREATE TRIGGER maj_somme AFTER INSERT OR UPDATE OR DELETE ON detail FOR EACH ROW EXECUTE PROCEDURE calc_somme();
Mais n'essayez pas de simplement remplacer des morceaux en espérant que ça marche. Il faut vraiment que vous vous appropriez le fonctionnement des triggers.
Au fait, sinon vous avez 10 fois plus simple, si vous voulez juste une 'table' qui contienne les sommes :
CREATE VIEW facture AS SELECT commande,sum(montant) AS somme FROM detail;
Marc.
Hors ligne
Pas du tout!!
J'ai modifié le code pour vraiment le personnaliser. C'est bon, ça y est ça marche.
Par contre, j'ai fait des recherches sur Tg_op. Je n'arrive pas à saisir son fonctionnement. La page de PostgreSQL n'est pas claire à ce sujet. J'ai cherché mais ne suis tombé que sur des posts qui ont des problèmes avec mais pas d'explication particulière.
Je ne veux pas abuser de votre générosité Marc, vous m'avez sorti d'un sacré pétrin.
En tout cas voilà un merci sincère...
Hors ligne
C'est assez simple : TG_OP contient le type d'opération qui a déclenché le trigger. On pourrait très bien imaginer faire 3 triggers différents, un par type d'opération. C'est un choix, en termes de lisibilité.
La doc sur le sujet : http://docs.postgresql.fr/8.4/plpgsql-trigger.html
D'ailleurs mon code en était assez fortement inspiré.
Marc.
Hors ligne
d'accord... J'avais besoin que cela soit présenté ainsi.
C'est juste un gain en rapidité.
J'avais vu déjà le lien. Mais honnêtement, il y a tellement de types de triggers qu'il y a de quoi se perdre.
J'arrête ici mes questionnements mais recommence mes remerciements.
A bientôt Marc et bonne continuation jusque là,
LeHibou
Hors ligne
Pages : 1