IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Firebird Discussion :

Trigger et gestion compteur


Sujet :

Firebird

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2002
    Messages : 22
    Points : 30
    Points
    30
    Par défaut Trigger et gestion compteur
    Bonjour,

    J'ai 3 tables Compteurs, Entête Factures et Lignes Factures; à chaque nouvelle facture, j'incrémente le compteur de n° de facture dans la table Compteurs.
    Est-il possible de gérer le compteur de n° de facture via un trigger lors de chaque insertion d'un entête de facture ? (je compte récupérer le numéro généré via RETURNING into ...). Etant newbie en SQL , je ne sais pas comment procéder pour écrire/créer un trigger pour faire cela ... J'ai lu bien des exemples de trigger, mais rien qui se rapproche de mon cas ou bien qui pourrait me mettre sur une piste. Merci d'avance pour votre aide.
    NB : Le N° de facture ne peut pas être géré via un champ auto-increment, mais au sein d'une table dédiée à cet effet.

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut
    Bonjour,
    Citation Envoyé par Noel Sybille Voir le message
    Le N° de facture ne peut pas être géré via un champ auto-increment, mais au sein d'une table dédiée à cet effet.
    Tout à fait d'accord, cependant utiliser un Trigger ne va pas empêcher les "trous" dans la facturation si une insertion est faite puis annulée il faut être conscient de ce fait !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    CREATE TABLE ENTETE_FACTURE
    (
      IDINTERNE BIGINT NOT NULL,
      ANNEE INTEGER,
      NUMERO INTEGER,
      CONSTRAINT PK_ENTETE_FACTURE PRIMARY KEY (IDINTERNE)
    );
     
    CREATE UNIQUE INDEX IDX_ENTETE_FACTURE ON ENTETE_FACTURE (ANNEE,NUMERO);
     
    CREATE TABLE COMPTEUR_FACTURE
    (
      ANNEE INTEGER NOT NULL,
      NUMERO INTEGER,
      CONSTRAINT PK_COMPTEUR_FACTURE PRIMARY KEY (ANNEE)
    );
    pour l'identification interne, voici ce que donnerai le trigger
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    CREATE GENERATOR GEN_ENTETE_FACTURE_ID;
     
    SET TERM !! ;
    CREATE TRIGGER ENTETE_FACTURE_BI FOR ENTETE_FACTURE
    ACTIVE BEFORE INSERT POSITION 0
    AS
    DECLARE VARIABLE tmp DECIMAL(18,0);
    BEGIN
      IF (NEW.IDINTERNE IS NULL) THEN
        NEW.IDINTERNE = GEN_ID(GEN_ENTETE_FACTURE_ID, 1);
      ELSE
      BEGIN
        tmp = GEN_ID(GEN_ENTETE_FACTURE_ID, 0);
        if (tmp < new.IDINTERNE) then
          tmp = GEN_ID(GEN_ENTETE_FACTURE_ID, new.IDINTERNE-tmp);
      END
    -- ici 
    END!!
    SET TERM ; !!
    il suffit de rajouter le code concernant le compteur
    1° Méthode
    on prend le numéro avant de modifier le compteur;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    -- à insérer après le calcul de l'id 
    SELECT COALESCE(NUMERO,0)+1 FROM COMPTEUR_FACTURE WHERE ANNEE=NEW.ANNEE INTO NEW.NUMERO;
    UPDATE OR INSERT INTO  COMPTEUR_FACTURE (ANNEE,NUMERO) VALUES NEW.ANNEE,NEW.NUMERO MATCHING (ANNEE);
    2°Méthode
    on modifie le compteur AVANT
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    SET TERM ^ ;
    ALTER TRIGGER ENTETE_FACTURE_BI ACTIVE
    BEFORE INSERT POSITION 0
    AS
    DECLARE VARIABLE tmp DECIMAL(18,0);
    DECLARE VARIABLE R INTEGER;
    BEGIN
      IF (NEW.IDINTERNE IS NULL) THEN
        NEW.IDINTERNE = GEN_ID(GEN_ENTETE_FACTURE_ID, 1);
      ELSE
      BEGIN
        tmp = GEN_ID(GEN_ENTETE_FACTURE_ID, 0);
        if (tmp < new.IDINTERNE) then
          tmp = GEN_ID(GEN_ENTETE_FACTURE_ID, new.IDINTERNE-tmp);
      END
     SELECT ANNEE FROM COMPTEUR_FACTURE WHERE ANNEE=NEW.ANNEE INTO :R; 
     IF (R IS NULL)
      THEN INSERT INTO COMPTEUR_FACTURE(ANNEE,NUMERO) VALUES (NEW.ANNEE,1) RETURNING NUMERO INTO NEW.NUMERO;
      ELSE UPDATE COMPTEUR_FACTURE SET NUMERO=NUMERO+1 WHERE ANNEE=NEW.ANNEE RETURNING NUMERO INTO NEW.NUMERO; 
    END^
    SET TERM ; ^
    3°Méthode
    là je doit avouer avoir galéré avec la syntaxe de MERGE que je n'arrive pas à faire fonctionner si l'année n'existe pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    MERGE INTO COMPTEUR_FACTURE C 
     USING (SELECT ANNEE, COALESCE(NUMERO,0) AS NUM FROM COMPTEUR_FACTURE) N ON (C.ANNEE=N.ANNEE)
     WHEN MATCHED THEN UPDATE SET NUMERO=N.NUM+1; 
    -- la partie not matched ne fonctionne pas 
     WHEN NOT MATCHED THEN INSERT (ANNEE,NUMERO) VALUES (NEW.ANNEE,1);
    de plus MERGE ne semble pas retourner de valeur ?
    si quelqu'un peut jeter un coup d’œil
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2002
    Messages : 22
    Points : 30
    Points
    30
    Par défaut
    Mille mercis pour votre réponse !
    J'avais bossé dessus ce matin et était arrivée à un "code" similaire, mais ma synthaxe est complètement erronée par méconnaissance du SQL...

    Tout à fait d'accord, cependant utiliser un Trigger ne va pas empêcher les "trous" dans la facturation si une insertion est faite puis annulée il faut être conscient de ce fait !
    Oui, si une facture doit être supprimée, l'utilisateur pourra, après vérification que le n° est disponible, forcer un numéro précis pour une nouvelle facture.
    Dans ce cas, NEW.IDINTERNE ne sera pas Null.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CREATE GENERATOR GEN_ENTETE_FACTURE_ID;
    Je ne comprends pas l'utilisation de ce "generator" puisque mon compteur est géré via une table (un record=une année).
    Pour la gestion du compteur, je préfère la 2ème méthode (on modifie le compteur AVANT et on la récupère via RETURNING; je pense que c'est + safe en multi-utilisateurs :-)

    Pour la 3° méthode avec le MERGE, là, je patauge complètement... on oublie !

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut
    Je ne comprends pas l'utilisation de ce "generator" puisque mon compteur est géré via une table (un record=une année).
    une simple précaution que mon expérience me fait mettre en place systématiquement pour toute table ayant un index primaire non numérique ou composé , pas forcément une obligation donc. Dans ce jeu d'essai cela permet aussi de montrer ce qui peut se passer avec un simple générateur
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [2000] Trigger pour gestion de doublon sur un champ
    Par Banzai31 dans le forum Développement
    Réponses: 7
    Dernier message: 28/10/2014, 18h36
  2. Trigger de gestion de stock
    Par Rahanin dans le forum Débuter
    Réponses: 12
    Dernier message: 06/05/2010, 14h49
  3. Triggers de gestion de stock
    Par shadypierre dans le forum SQL Procédural
    Réponses: 9
    Dernier message: 12/02/2009, 16h20
  4. Trigger remise a 0 compteur
    Par koolkris dans le forum SQL
    Réponses: 8
    Dernier message: 15/02/2005, 15h37
  5. [PB CONCEPTUEL] avec compteur/trigger
    Par kase74 dans le forum SQL
    Réponses: 6
    Dernier message: 25/03/2004, 11h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo