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

SQL Firebird Discussion :

[FB 1.5] insert avec FK


Sujet :

SQL Firebird

  1. #1
    Membre chevronné
    Avatar de free07
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    931
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 931
    Points : 1 909
    Points
    1 909
    Par défaut [FB 1.5] insert avec FK
    Bonjour,

    j'ai deux tables :
    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
     
    la première :
    CREATE TABLE ENTFACT (
        ID                     BIGINT NOT NULL,
        EF_NUMPOSTE            VARCHAR(3),
        EF_DATEFACTURE         DATE,
        EF_HEUREFACTURE        TIME,
        EF_ETAT                CHAR(1),
        EF_CODECLIENT          VARCHAR(15),
        ...
    );
     
    ALTER TABLE ENTFACT ADD PRIMARY KEY (ID);
     
    et la seconde :
    CREATE TABLE LIGFACT (
        ID                    BIGINT NOT NULL,
        LF_NUMLIGNE           INTEGER NOT NULL,
        LF_TYPELIGNE          SMALLINT,
        LF_CODECONSO          VARCHAR(15),
        LF_LIBELLECONSO       VARCHAR(80),
        LF_QUANTITE           INTEGER,
        ...
    );
    ALTER TABLE LIGFACT ADD CONSTRAINT PK_LIGFACT PRIMARY KEY (ID, LF_NUMLIGNE);
    J'ai crée une FK comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    alter table LIGFACT
    add constraint FK_LIGFACT_1
    foreign key (ID)
    references ENTFACT (ID)
    on delete CASCADE
    on update CASCADE
    Sur la première table, la valeur de la clé (ID) s'incrémente automatiquement à l'aide d'un générateur et d'un trigger à chaque insert.

    Mon problème est le suivant :
    Je fais un insert d'une facture en mettant à jour les deux tables dans une meme transaction, lorsque je commit, j'ai le message suivant :
    Violation of Foreign Key constraint "FK_LIGFACT_1" on table "LIGFACT"

    Pour faire + simple :
    Dans une meme transaction, comment faire un insert sur deux tables T1 et T2, sachant que la clé de T1 est auto incrémenté et que sur T2, il y a une FK qui pointe sur la clé de T1 ?
    Merci d'avance
    Thierry

  2. #2
    Membre éprouvé
    Avatar de Andry
    Profil pro
    Informaticien
    Inscrit en
    Juillet 2002
    Messages
    1 164
    Détails du profil
    Informations personnelles :
    Localisation : Madagascar

    Informations professionnelles :
    Activité : Informaticien

    Informations forums :
    Inscription : Juillet 2002
    Messages : 1 164
    Points : 1 181
    Points
    1 181
    Par défaut
    La solution que j'utilise frequement est d'utiliser une PS qui regroupe :
    - Recuperation de l'Id auto et le retourne
    - Insertion dans la table 1
    Le voici :
    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 PROCEDURE ENTFACT_INSERT (
        EF_NUMPOSTE            VARCHAR(3), 
        EF_DATEFACTURE         DATE, 
        EF_HEUREFACTURE        TIME, 
        EF_ETAT                CHAR(1), 
        EF_CODECLIENT          VARCHAR(15)) 
    RETURNS (
        ID                     BIGINT NOT NULL)
     
    AS
    BEGIN
      ID = GEN_ID(GEN_ENTFACT_NO,1); 
    /*Supposons que GEN_ENTFACT_NO est le nom du Generateur*/
      INSERT INTO ENTFACT (
        ID,
        EF_NUMPOSTE, 
        EF_DATEFACTURE, 
        EF_HEUREFACTURE, 
        EF_ETAT, 
        EF_CODECLIENT)
      VALUES (
        :ID,
        :EF_NUMPOSTE, 
        :EF_DATEFACTURE, 
        :EF_HEUREFACTURE, 
        :EF_ETAT, 
        :EF_CODECLIENT);
    END
    Avec ça non seulement, tu as inserer dans ta table ENTFACT mais aussi tu sais quelle ID tu as inserer.

    Il ne te reste qu'à recuperer cette ID pour inserer dans le second Table.

    A+
    On progresse .....

  3. #3
    Membre chevronné
    Avatar de free07
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    931
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 931
    Points : 1 909
    Points
    1 909
    Par défaut
    C'est une bonne idée, mais mon problème n'est pas là, en fait je m'aperçois que c'est au niveau de l'utilisation de IBSQL, il faut que j'insère mes infos dans les deux tables en meme temps sinon j'ai l'erreur de violation de la FK et je ne sais pas comment on peut faire deux insert avec un IBSQL
    Merci pour ton aide !

  4. #4
    Membre éprouvé
    Avatar de Andry
    Profil pro
    Informaticien
    Inscrit en
    Juillet 2002
    Messages
    1 164
    Détails du profil
    Informations personnelles :
    Localisation : Madagascar

    Informations professionnelles :
    Activité : Informaticien

    Informations forums :
    Inscription : Juillet 2002
    Messages : 1 164
    Points : 1 181
    Points
    1 181
    Par défaut
    D'habitude, j'insère dans les 2 tables dans la même transaction et ça marche bien, mais j'utilise des PS à la place.
    Je ne vois pas pourquoi cela ne marche pas dans ton cas.

    Mais montre ton code d'insertion pour voir .

    A+
    On progresse .....

  5. #5
    Membre chevronné
    Avatar de free07
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    931
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 931
    Points : 1 909
    Points
    1 909
    Par défaut
    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
     
        IBTransaction->StartTransaction();
        // on crée un nouvel entête de facture :
        IBSQL->SQL->Clear();
        IBSQL->SQL->Add("INSERT INTO ENTFACT (EF_NUMPOSTE, EF_DATEFACTURE, EF_HEUREFACTURE, EF_ETAT, EF_CODECLIENT, ... ");
        IBSQL->SQL->Add("VALUES (:NP, :DF, :HF, :ETA, :CC, ...)");
        IBSQL->ParamByName("NP")->AsString = l_sNomPoste;
        IBSQL->ParamByName("DF")->AsDate = P_Entete.DateFacture - 1;
        IBSQL->ParamByName("HF")->AsTime = 0;
        IBSQL->ParamByName("CC")->AsString = P_InfoClient.sCode;
        ...
        IBSQL->ExecQuery();  <-- exception : violation de la FK içi
     
        // insertion de lignes de facture
        IBSQL->SQL->Clear();
        IBSQL->SQL->Add("INSERT INTO LIGFACT (ID, LF_NUMLIGNE, LF_TYPELIGNE, LF_CODECONSO, LF_LIBELLECONSO, LF_QUANTITE, ...");
        IBSQL->SQL->Add("VALUES (:ID, :NL, :TL, :CC, :LC, :QT, ...)");
        IBSQL->ParamByName("ID")->Value = P_Entete.dNumFacture;
        IBSQL->ParamByName("NL")->Value = P_pListeConso->pCo_iNumLigne;
        IBSQL->ParamByName("TL")->Value = P_pListeConso->pCo_iTypeLigne;
        IBSQL->ParamByName("CC")->AsString = P_pListeConso->pCo_sCode;
       ...
       IBSQL->ExecQuery();
       IBTransaction->Commit(); // Fin de la transaction.
    J'ai simplifié le code car je mets à jours pas mal de colonnes sur les deux tables.
    J'ai l'erreur de violation de la FK au premier IBSQL->ExecQuery();
    Cela m'étonne pas car à ce moment là, la seconde table LIGFACT n'est pas du tout renseigné, je pense qu'il faut que je fasse les 2 inserts en meme temps mais je ne sais pas comment faire, je débute en SQL
    Merci pour ton aide

  6. #6
    Membre éprouvé
    Avatar de Andry
    Profil pro
    Informaticien
    Inscrit en
    Juillet 2002
    Messages
    1 164
    Détails du profil
    Informations personnelles :
    Localisation : Madagascar

    Informations professionnelles :
    Activité : Informaticien

    Informations forums :
    Inscription : Juillet 2002
    Messages : 1 164
    Points : 1 181
    Points
    1 181
    Par défaut
    Si j'analyse ton code, normalement , la violation de FK ne se passera que sur la deuxième ExecSQL mais pas sur l première.

    Mais, je vais voir en profondeur et faire des test.

    A+
    On progresse .....

  7. #7
    Expert confirmé

    Profil pro
    Inscrit en
    Avril 2002
    Messages
    3 338
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 338
    Points : 4 657
    Points
    4 657
    Par défaut
    A mon humble avis tu as mis ta procedure stocké à l'envers...

    Tu as dit que ta facture doit posséder des lignes de facture, alors que c'est l'inverse qu'il faut faire, les lignes de factures doivent posséder une facture.

    ou alors, inverse tes 2 requetes SQL.

  8. #8
    Membre chevronné
    Avatar de free07
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    931
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 931
    Points : 1 909
    Points
    1 909
    Par défaut
    Citation Envoyé par Gaël Donat
    A mon humble avis tu as mis ta procedure stocké à l'envers...

    Tu as dit que ta facture doit posséder des lignes de facture, alors que c'est l'inverse qu'il faut faire, les lignes de factures doivent posséder une facture.
    Je pense que tu dois parler de ma clé étrangère, de toute façon, je ne peux pas le faire dans l'autre sens vu qu'une FK ne peut pointer que sur une clé unique et comme ma seconde table possède une clé composé de deux colonnes...

    ou alors, inverse tes 2 requetes SQL.
    Je l'ai fait et cela donne le meme résultat

    Merci pour l'intérêt que tu portes à mon problème
    Thierry
    [/quote]

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

Discussions similaires

  1. [INSERT][SELECT] insert avec un select imbriqué
    Par narmataru dans le forum SQL
    Réponses: 11
    Dernier message: 06/03/2013, 03h04
  2. [Procédure stockée]Insert avec renvoi clé primaire?
    Par busmik dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 26/08/2004, 16h14
  3. effectuer une requete insert avec 'values' ET 'select'
    Par delaio dans le forum Bases de données
    Réponses: 4
    Dernier message: 15/08/2004, 19h05
  4. INSERT avec procédure stockée / Clef de type AutoInc
    Par bgdelphi dans le forum Bases de données
    Réponses: 5
    Dernier message: 18/10/2003, 18h30
  5. Problème d'insertion avec MySQL
    Par Sonny dans le forum ASP
    Réponses: 13
    Dernier message: 28/08/2003, 13h52

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