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

Bases de données Delphi Discussion :

Problème de generateur de clé primaire


Sujet :

Bases de données Delphi

  1. #1
    Membre du Club
    Inscrit en
    Juillet 2002
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 84
    Points : 67
    Points
    67
    Par défaut Problème de generateur de clé primaire
    Bonjour,

    J'ai deux tables qui ont chacunes leur propre générateur de clé primaire mais ils ne s'incrémentent pas de un en un comme je le voudrais.
    On dirait qu'ils croissent selon une suite géométrique. Ex:

    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
     
    PED_ID
    -------
    26
    29
    33
    38
    44
    51
    59
    68
     
    26+3=29
    29+4=33
    33+5=38
    38+6=44
    etc.
    Voici un extrait du code qui gère ceci :
    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
     
    IBSQL_Venda.SQL.Clear;
    IBSQL_Venda.SQL.Append('SELECT GEN_ID(PEDIDOS_GEN_ID, 1) AS ID FROM PEDIDOS;');
    IBSQL_Venda.ExecQuery;
    PedId := IBSQL_Venda.FieldByName('ID').AsString;
    IBSQL_Venda.Close;
    IBSQL_Venda.SQL.Clear;
    IBSQL_Venda.SQL.Append('INSERT INTO PEDIDOS (PED_ID, ...) ');
    IBSQL_Venda.SQL.Append('VALUES (:pedID, ...);');
    IBSQL_Venda.ParamByName('pedID').AsString := PedId;
    IBSQL_Venda.ExecQuery;
    IBSQL_Venda.Close;
    for Index := 1 to StrGrid_Venda.RowCount-1 do
    begin
      IBSQL_Venda.SQL.Clear;
      IBSQL_Venda.SQL.Append('SELECT GEN_ID(ITENS_PEDIDOS_GEN_ID, 1) AS ID FROM ITENS_PEDIDOS;');
      IBSQL_Venda.ExecQuery;
      IpeId := IBSQL_Venda.FieldByName('ID').AsString;
      IBSQL_Venda.Close;
      IBSQL_Venda.SQL.Clear;
      IBSQL_Venda.SQL.Append('INSERT INTO ITENS_PEDIDOS (IPE_ID, ...) ');
      IBSQL_Venda.SQL.Append('VALUES (:ipeID, ...);');
      IBSQL_Venda.ParamByName('ipeID').AsString := IpeId;
      IBSQL_Venda.ExecQuery;
      IBSQL_Venda.Close;
    end;
    Si quelqu'un a une idée?

    Cyril

  2. #2
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Salut !

    Une chose est certaine tu as un appel multiple aux GEN_ID ! Ton code est dans l'absolu correct même si il peut être simplifié.

    Je trouve aussi curieux que tu travailles avec des strings pour tes IDs. Les champs autoincrémentés sont des Integer. Non !

    Une partie de l'explication viendrait du fait qu'un trigger sur ta table incrémente à nouveau la valeur de l'ID. Mais cela ne suffit à expliquer la progression géométrique, tu dois avoir d'autres appels dans ton code (BeforeInsert, BeforePost, ...).

    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
     
    var
      Index, PedID: Integer;
    begin
      with IBSQL_Venda do begin
        // PEDIDOS
        SQL.Clear;
        SQL.Append('INSERT INTO PEDIDOS (PED_ID, ...)');
        SQL.Append('VALUES (GEN_ID(PEDIDOS_GEN_ID,1), ...);');
        ExecQuery;
        Close;
     
        // Récupération de l'ID attribué (si stocké dans ITENS_PEDIDOS)
        SQL.Clear;
        SQL.Append('SELECT GEN_ID(PEDIDOS_GEN_ID, 0) FROM RDB$DATABASE');
        ExecQuery;
        PedID := Fields[0].AsInteger;
        Close;
     
        // ITENS_PEDIDOS
        for Index := 1 to StrGrid_Venda.RowCount-1 do
        begin
          SQL.Clear;
          SQL.Append('INSERT INTO ITENS_PEDIDOS (IPE_ID, PED_ID, ...) ');
          SQL.Append('VALUES (GEN_ID(ITENS_PEDIDOS_GEN_ID,1), :PedID, ...);');
          ParamByName('PedID').AsInteger := PedID;
          ExecQuery;
          Close;
        end;
      end;
    end;
    @+ Claudius

  3. #3
    Membre du Club
    Inscrit en
    Juillet 2002
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 84
    Points : 67
    Points
    67
    Par défaut
    Salut Claudius,

    J'utilise des String pour mon ID par praticité car comme l'ID entre aussi dans des champs qui eux sont du type VARCHAR, cela m'évite d'utiliser tout le temps la fonction IntToStr(), bref ceci est un détail...

    J'ai changé mon code et copié ton exemple mais cela ne fonctionne pas car, apparamment, quand on utilise GEN_ID(...) dans les VALUES, il y a un conflit avec la transaction car j'ai une erreur de clé étrangère lors des insertions dans la seconde table.

    J'avais déjà essayé auparavent :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INSERT INTO TABLE (...)
    SELECT GEN_ID(mon_GEN, 1), ... FROM TABLE
    Mais cela n'avait pas fonctionné non plus...


    Cyril

  4. #4
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Bom-dia Cyril !

    Tu as des triggers Before Insert sur tes deux tables qui appelle les GEN_ID ?

    Le problème de l'ID intervient sur quelle table: PEDIDOS ou ITENS_PEDIDOS (ou les deux) ?

    @+

  5. #5
    Membre du Club
    Inscrit en
    Juillet 2002
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 84
    Points : 67
    Points
    67
    Par défaut
    Tout d'abord je reviens sur ce que j'ai dit À propos de ton code car je me suis aperçu que je ne savais même pas copier correctement ! (J'étais déjà comme ça en MIAGE...)

    Tu as écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    // Récupération de l'ID attribué (si stocké dans ITENS_PEDIDOS)
     SQL.Clear;
     SQL.Append('SELECT GEN_ID(PEDIDOS_GEN_ID, 0) FROM RDB$DATABASE');
     ExecQuery;
     PedID := Fields[0].AsInteger;
     Close;
    et j'ai copié :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    // Récupération de l'ID attribué (si stocké dans ITENS_PEDIDOS)
     SQL.Clear;
     SQL.Append('SELECT GEN_ID(PEDIDOS_GEN_ID, 1) FROM
    RDB$DATABASE');
     ExecQuery;
     PedID := Fields[0].AsInteger;
     Close;
    Donc forcément, cela ne pouvait pas fonctionner...

    Le problème est à présent résolu car je me suis arrêté pour penser (longuement...) et j'en ai tiré une conclusion (si, si, tout seul, comme un grand!) qui est la suivante : Pourquoi faire soi même ce qu'un autre peut faire ?

    Alors du coup j'ai créer des trigger Before insert qui gèrent les clés primaires pour moi (et apparamment, après test, il le font mieux que moi!), comme ça je peux faire autre chose...

    Mais merci tout de même pour le coup de pied euh.. non de pouce (dans l'oeil)

  6. #6
    Membre du Club
    Inscrit en
    Juillet 2002
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 84
    Points : 67
    Points
    67
    Par défaut
    Pour en revenir à ta dernière question, j'ai ce problème non pas sur ces 2 tables mais sur toutes les tables de ma base !!
    Mais comme j'ai, les triggers ont tout résolu.

    Cyril.

  7. #7
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Citation Envoyé par cgone
    Alors du coup j'ai créer des trigger Before insert qui gèrent les clés primaires pour moi (et apparamment, après test, il le font mieux que moi)
    Bon réflexe Dans le domaine des incréments, il faut autant que possible laisser travailler la base, via les triggers et GEN_ID.

    Citation Envoyé par cgone
    comme ça je peux faire autre chose...

    @+ Claudius

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

Discussions similaires

  1. [Doctrine] Fichier yaml avec clé primaire multi-colonnes
    Par butters dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 19/07/2010, 14h23
  2. Problème sur génération de clé primaire
    Par trouffiondesiles dans le forum ASP.NET
    Réponses: 4
    Dernier message: 08/11/2009, 21h01
  3. Problème pour créer une clé primaire
    Par grahamm dans le forum Modélisation
    Réponses: 6
    Dernier message: 25/08/2008, 14h49
  4. Problème de modification de clé primaire via Hibernate
    Par mrjeronimo dans le forum Hibernate
    Réponses: 9
    Dernier message: 31/03/2008, 18h28
  5. Problème pour récupérer la clé primaire
    Par caramel dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 11/04/2003, 13h57

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