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 :

liaison entre tables


Sujet :

Firebird

  1. #1
    Membre du Club
    Profil pro
    Retraité
    Inscrit en
    Avril 2004
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Avril 2004
    Messages : 74
    Points : 69
    Points
    69
    Par défaut liaison entre tables
    Bonjour,
    J'ai deux tables clients et ventes liées par un clé étrangère et avec l'intégrité référentielle en cascade.
    Dans un trigger de la table clients, je détermine la clé d'un nouveau client. Tout marche bien jusque là... Mais si dans ce trigger je veux insérer la valeur de cette clé comme clé étrangère dans la table ventes (INSERT INTO VENTES (ID_CLIENT) VALUES (:idclient); ), j'obtiens une violation de contrainte.
    Certainement due au fait que la transaction d'insertion dans la table client n'est pas terminée. Cependant, comment valider la transaction et insérer la nouvelle valeur dans la table ventes. L'insertion d'un COMMIT n'est pas accepté dans le trigger?
    Quelque chose m'échappe et je n'arrive pas à comprendre ?

    Merci pour un éclairage ou l'aiguillage vers un tuto ou un exemple similaire...

    Michel
    j'aimerai savoir ...

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 042
    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 042
    Points : 40 952
    Points
    40 952
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    Le code source du/des triggers aurait été un plus . (la version de Firebird aussi)

    L'insertion d'un COMMIT n'est pas accepté dans le trigger?
    à ma connaissance si
    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
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    à ma connaissance si
    pardon ?
    non

    et pas besoin, par contre il faut un trigger before insert, pas after
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 042
    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 042
    Points : 40 952
    Points
    40 952
    Billets dans le blog
    62
    Par défaut
    j'ai encore confondu ou écrit trop vite
    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

  5. #5
    Membre du Club
    Profil pro
    Retraité
    Inscrit en
    Avril 2004
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Avril 2004
    Messages : 74
    Points : 69
    Points
    69
    Par défaut Liaison entre tables
    Bonjour,

    Quelques jours d'absence....

    Il s'agit de la version firebird 2.5.

    J'ai bien compris qu'on ne pouvait pas utiliser COMMIT dans un trigger.

    Voici le code du trigger avec en remarque le code qui ne passe pas à la fin du texte.
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    declare variable dateAn varchar(4);
    declare variable datejour varchar(7);
    declare variable nbcli integer;
    declare variable nbclichar varchar(10);
    declare variable idclient varchar(20);
     
     
    begin
      /* Trigger text */
        dateAn = cast( extract(year  from current_date) as char(4));
        datejour = :dateAn || '-' || substring(cast(100 + extract(month from current_date) as varchar(3)) from 2);
        nbclichar = '';
     
        SELECT MAX(id_client)
        FROM my
        where my.id_client like (:datejour || '%')
        into :nbclichar;
     
        If  (:nbclichar <> '') Then 
            begin
             nbcli = 101 + (cast(substring(:nbclichar from 9 for 2) AS Integer));
             nbclichar =  substring(cast(:nbcli AS varchar(3))from 2) ;
            end  
            else  nbclichar = '01'; 
     
        idclient =  :datejour ||'-' || CAST(:nbclichar as varchar(2)) ;
        new.id_client =  :idclient;
        new.date_1er_achat = current_date;
        new.date_der_achat = current_date;
     
       /* INSERT INTO VENTES (ID_CLIENT)
        VALUES (:idclient);      ce code ne passe pas pour la table ""ventes" */  
    end
    Merci de votre première réponse.

    Michel
    j'aimerai savoir ...

  6. #6
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    et la déclaration du trigger ?
    la structure des tables ?
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  7. #7
    Membre du Club
    Profil pro
    Retraité
    Inscrit en
    Avril 2004
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Avril 2004
    Messages : 74
    Points : 69
    Points
    69
    Par défaut Liaison entre tables
    Je n'avais pas tout compris...

    Je ne pensai pas que le code des triggers était intégré das le DDL de chaque table.

    Voici la table client(MY)
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    CREATE TABLE MY 
    (
      ID_CLIENT                IDX_UNIQUE ,
      TITRE                  TITREDOMAINE ,
      NOM                        IDENTITE NOT NULL,
      PRENOM                 TITREDOMAINE ,
      ADRESSE_1                   ADRESSE ,
      ADRESSE_2                   ADRESSE ,
      VILLE                      IDENTITE ,
      CODE_POSTAL                      CP ,
      DATE_1ER_ACHAT                 DATE,
      DATE_DER_ACHAT                 DATE,
      CARTE_FIDELITE              NON_OUI ,
      NPAI                        NON_OUI ,
      REPONSE_MAIL                NON_OUI ,
     CONSTRAINT PK_MY PRIMARY KEY (ID_CLIENT)
    );
    update rdb$relation_fields set rdb$description = 'Index calcul' where rdb$relation_name = 'MY' and rdb$field_name = 'ID_CLIENT';
    update rdb$relation_fields set rdb$description = 'VARCHAR 35 UPPER' where rdb$relation_name = 'MY' and rdb$field_name = 'TITRE';
    update rdb$relation_fields set rdb$description = 'VARCHAR 35 UPPER' where rdb$relation_name = 'MY' and rdb$field_name = 'NOM';
    update rdb$relation_fields set rdb$description = 'VARCHAR 35 UPPER' where rdb$relation_name = 'MY' and rdb$field_name = 'PRENOM';
    update rdb$relation_fields set rdb$description = 'Majuscules' where rdb$relation_name = 'MY' and rdb$field_name = 'ADRESSE_1';
    update rdb$relation_fields set rdb$description = 'Majuscules' where rdb$relation_name = 'MY' and rdb$field_name = 'ADRESSE_2';
    update rdb$relation_fields set rdb$description = 'VARCHAR 35 UPPER' where rdb$relation_name = 'MY' and rdb$field_name = 'VILLE';
    update rdb$relation_fields set rdb$description = 'Char numerique' where rdb$relation_name = 'MY' and rdb$field_name = 'CODE_POSTAL';
    update rdb$relation_fields set rdb$description = 'Date
    Char numerique' where rdb$relation_name = 'MY' and rdb$field_name = 'DATE_1ER_ACHAT';
    update rdb$relation_fields set rdb$description = 'Date
    Char numerique' where rdb$relation_name = 'MY' and rdb$field_name = 'DATE_DER_ACHAT';
    update rdb$relation_fields set rdb$description = 'Boolean Non par d' where rdb$relation_name = 'MY' and rdb$field_name = 'CARTE_FIDELITE';
    update rdb$relation_fields set rdb$description = 'Boolean Non par d' where rdb$relation_name = 'MY' and rdb$field_name = 'NPAI';
    CREATE ASC INDEX IDX_MY_1ER_ACHAT ON MY (DATE_1ER_ACHAT);
    CREATE ASC INDEX IDX_MY_ADRESSE1 ON MY (ADRESSE_1);
    CREATE ASC INDEX IDX_MY_CP ON MY (CODE_POSTAL);
    CREATE ASC INDEX IDX_MY_DER_ACHAT ON MY (DATE_DER_ACHAT);
    CREATE ASC INDEX IDX_MY_NOM ON MY (NOM);
    CREATE ASC INDEX IDX_MY_VILLE ON MY (VILLE);
    CREATE UNIQUE DESC INDEX ID_CLIENT ON MY (ID_CLIENT);
    SET TERM ^^ ;
    CREATE TRIGGER MY_BI1 FOR MY ACTIVE BEFORE INSERT POSITION 0 AS
    declare variable dateAn varchar(4);
    declare variable datejour varchar(7);
    declare variable nbcli integer;
    declare variable nbclichar varchar(10);
    declare variable idclient varchar(20);
     
     
    begin
      /* Trigger text */
        dateAn = cast( extract(year  from current_date) as char(4));
        datejour = :dateAn || '-' || substring(cast(100 + extract(month from current_date) as varchar(3)) from 2);
        nbclichar = '';
     
        SELECT MAX(id_client)
        FROM my
        where my.id_client like (:datejour || '%')
        into :nbclichar;
     
        If  (:nbclichar <> '') Then 
            begin
             nbcli = 101 + (cast(substring(:nbclichar from 9 for 2) AS Integer));
             nbclichar =  substring(cast(:nbcli AS varchar(3))from 2) ;
            end  
            else  nbclichar = '01'; 
     
        idclient =  :datejour ||'-' || CAST(:nbclichar as varchar(2)) ;
        new.id_client =  :idclient;
        new.date_1er_achat = current_date;
        new.date_der_achat = current_date;
     
       /* INSERT INTO VENTES (ID_CLIENT)
        VALUES (:idclient);      ce code ne passe pas pour la table ""ventes" */  
    end ^^
    SET TERM ; ^^
    et la table ventes

    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
    22
    23
    24
    25
    26
    27
    28
    29
    CREATE TABLE VENTES 
    (
      IDX_VENTE                 INDEX_NUM ,
      ID_CLIENT             INDEX_CALCULE ,
      ARTICLE                     INTEGER,
      PRIX                        DECIMAL( 15, 2),
      DATE_DER_ACHAT               "DATE" ,
     CONSTRAINT PK_VENTES PRIMARY KEY (IDX_VENTE)
    );
    update rdb$relation_fields set rdb$description = 'Index calcul' where rdb$relation_name = 'VENTES' and rdb$field_name = 'ID_CLIENT';
    update rdb$relation_fields set rdb$description = 'Date
    Char numerique' where rdb$relation_name = 'VENTES' and rdb$field_name = 'DATE_DER_ACHAT';
    ALTER TABLE VENTES ADD CONSTRAINT FK_VENTES_1 
      FOREIGN KEY (ID_CLIENT) REFERENCES MY
      (ID_CLIENT) 
      ON DELETE CASCADE
      ON UPDATE CASCADE
    ;
    CREATE DESC INDEX VENTES_ID_CLIENT ON VENTES (ID_CLIENT);
    SET TERM ^^ ;
    CREATE TRIGGER VENTES_BI0 FOR VENTES ACTIVE BEFORE INSERT POSITION 0 AS
    begin
      /* Trigger text */
      if (new.idx_vente is null) then
      NEW.idx_vente = gen_id(gen_ventes_id,1);
     
      new.date_der_achat = current_date;
    end ^^
    SET TERM ; ^^
    On apprend tous les jours
    Merci
    j'aimerai savoir ...

  8. #8
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 042
    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 042
    Points : 40 952
    Points
    40 952
    Billets dans le blog
    62
    Par défaut
    Bonsoir

    à la lecture de la relation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ALTER TABLE VENTES ADD CONSTRAINT FK_VENTES_1 FOREIGN KEY (ID_CLIENT) REFERENCES MY (ID_CLIENT)
    ce code devrait être dans un after insert
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      INSERT INTO VENTES (ID_CLIENT)
        VALUES (old.id_client);
    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

  9. #9
    Membre du Club
    Profil pro
    Retraité
    Inscrit en
    Avril 2004
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Avril 2004
    Messages : 74
    Points : 69
    Points
    69
    Par défaut Liaison entre tables
    Désolé,
    le code ne fonctionne pas et j'obtiens le message:

    violation of FOREIGN KEY constraint "FK_VENTES_1" on table "VENTES"
    Foreign key reference target does not exist
    At trigger 'MY_AFTER' line: 14, col: 3


    Après réflexion je me suis dit que c'était la valeur (OLD.ID_CLIENT) qui était null puisque c'est un nouvel enregistrement, mais rien n'y fait.

    L'erreur semble être au niveau de l'instruction INSERT (line: 14, col: 3).

    Voici le code du nouveau 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
    SET TERM ^^ ;
    CREATE TRIGGER MY_AFTER FOR MY ACTIVE BEFORE INSERT OR UPDATE POSITION 1 AS
    /*
      You can change this template in the template editor:
      File | Preferences | Object Templates
     
      Trigger:
     
      Author   : , 
      Date     : 13/12/2013 22:27:59
      Purpose  :
    */
    begin
      /* code */
      INSERT INTO VENTES (VENTES.ID_CLIENT)
        VALUES (NEW.ID_CLIENT);
    end ^^
    SET TERM ; ^^
    ?
    Merci de votre aide.
    j'aimerai savoir ...

  10. #10
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 042
    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 042
    Points : 40 952
    Points
    40 952
    Billets dans le blog
    62
    Par défaut
    par
    ce code devrait être dans un after insert
    je voulais dire quelque chose comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SET TERM ^^ ;
    CREATE TRIGGER MY_AFTER FOR MY ACTIVE AFTER INSERT OR UPDATE POSITION 1 AS
    begin
      /* code */
      INSERT INTO VENTES (VENTES.ID_CLIENT)
        VALUES (OLD.ID_CLIENT);
    end ^^
    SET TERM ; ^^
    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

  11. #11
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    par
    je voulais dire quelque chose comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SET TERM ^^ ;
    CREATE TRIGGER MY_AFTER FOR MY ACTIVE AFTER INSERT OR UPDATE POSITION 1 AS
    begin
      /* code */
      INSERT INTO VENTES (VENTES.ID_CLIENT)
        VALUES (OLD.ID_CLIENT);
    end ^^
    SET TERM ; ^^
    avec NEW.ID_CLIENT plutôt
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  12. #12
    Membre du Club
    Profil pro
    Retraité
    Inscrit en
    Avril 2004
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Avril 2004
    Messages : 74
    Points : 69
    Points
    69
    Par défaut
    Bonjour et merci SergioMaster,

    Je n'avais pas été assez attentif et je pensai que le trigger était déclré en AFTER

    ça marche

    Merci encore

    Michel
    j'aimerai savoir ...

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

Discussions similaires

  1. [VB.net] liaison entre table et textbox's
    Par collaud_vb dans le forum Windows Forms
    Réponses: 10
    Dernier message: 25/09/2006, 13h27
  2. [Access 2003]Problème de liaison entre table
    Par steeves5 dans le forum Access
    Réponses: 3
    Dernier message: 12/06/2006, 09h40
  3. [DEB] Probleme de liaison entre tables
    Par ip203 dans le forum Access
    Réponses: 4
    Dernier message: 07/06/2006, 07h16
  4. Liaison entre tables
    Par Thierry69800 dans le forum Access
    Réponses: 1
    Dernier message: 20/11/2005, 23h19
  5. Problèmes de liaisons entre tables ...
    Par Mangun dans le forum Access
    Réponses: 2
    Dernier message: 28/09/2005, 11h35

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