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 :

Récupérer la valeur d'un champ auto increment dans Firebird


Sujet :

Bases de données Delphi

  1. #1
    mls
    mls est déconnecté
    Membre à l'essai
    Inscrit en
    Mai 2004
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 18
    Points : 13
    Points
    13
    Par défaut Récupérer la valeur d'un champ auto increment dans Firebird
    Bonjour,

    J'ai un projet Delphi où j'insère un enregistrement dans une table ayant au auto increment en clé primaire.
    J'aimerai récupérer cette valeur de l'auto increment lorsque je viens de l'ajouter dans la table.

    Avec l'outil IBExpert, pas de problème, cela fonctionne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    INSERT INTO ma table (ch1, ch2, ...) VALUES (val1, val2, ....) RETURNING ch1;
    Cette syntaxe me permet de récupérer la valeur de l'auto increment venant d'être inséré (ici "ch1").


    Avec Delphi, voici le code que j'utilise (avec un TSimpleDataSet nommé DT) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ...
    DT.DataSet.CommandText := 'INSERT INTO ma_table (ch1, ch2, ...) VALUES (:val1, :val2, ....) RETURNING ch1';
    ...
    DT.Execute;
    ...
    L'insertion fonctionne parfaitement mais comment récupérer la valeur de l'auto increment venant d'être inséré dans "ch1" ?

    Merci beaucoup d'avance...

  2. #2
    Membre émérite
    Homme Profil pro
    Directeur technique
    Inscrit en
    Mai 2008
    Messages
    2 401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2008
    Messages : 2 401
    Points : 2 304
    Points
    2 304
    Par défaut
    Salut;

    je crois que tu peux la retrouver dans l'évènement beforeinsert ou beforepost.
    mais j'ai une remarque à faire, en général on n'utilise pas un champ auto incrément comme clé primaire c'est très difficile à maintenir surtout si tu fais des suppressions que ce champ est utilisé dans des relations maitre détail.
    Bon courage ou Bonne Chance (selon le contexte)
    Mon blog sur WordPress

  3. #3
    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
    Citation Envoyé par Just-Soft Voir le message
    Salut;
    mais j'ai une remarque à faire, en général on n'utilise pas un champ auto incrément comme clé primaire c'est très difficile à maintenir surtout si tu fais des suppressions que ce champ est utilisé dans des relations maitre détail.
    Et pourquoi donc est ce si difficile à maintenir ?
    La gestion des relations maitre/détail doit être mis au niveau de la base de donnée.
    mls >>>
    Le truc que je fais tous les jours c'est de récupérer la valeur du générateur avant l'insertion, et d'utiliser cette valeur dans les insertions.

    A+
    On progresse .....

  4. #4
    Membre émérite
    Homme Profil pro
    Directeur technique
    Inscrit en
    Mai 2008
    Messages
    2 401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2008
    Messages : 2 401
    Points : 2 304
    Points
    2 304
    Par défaut
    Citation Envoyé par Andry Voir le message
    Et pourquoi donc est ce si difficile à maintenir ?
    j'expose le problème de suppression qui entraine un décalage et pour y remédier on fait un compactage ou un ordonnancement, comment tu fais si tu as une relation maître/détail basé sur ce champ sachant que tu restructure ta base de données après les suppressions ?
    Bon courage ou Bonne Chance (selon le contexte)
    Mon blog sur WordPress

  5. #5
    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

    Citation Envoyé par mls Voir le message
    L'insertion fonctionne parfaitement mais comment récupérer la valeur de l'auto increment venant d'être inséré dans "ch1" ?
    Tu dois considérer cette valeur retournée comme un champ.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ...
    DT.DataSet.CommandText := 'INSERT INTO ma_table (ch1, ch2, ...) VALUES (:val1, :val2, ....) RETURNING ch1';
    ...
    DT.Execute;
    ID := DT.FieldByName('ch1').AsInteger;
    @+ Claudius

  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
    Citation Envoyé par Just-Soft Voir le message
    j'expose le problème de suppression qui entraine un décalage et pour y remédier on fait un compactage ou un ordonnancement, comment tu fais si tu as une relation maître/détail basé sur ce champ sachant que tu restructure ta base de données après les suppressions ?
    Généralement, ma clé primaire est juste un nombre sans signification particulier au niveau de ma table; dans la relation maitre/détail, la suppression est géré en cascade grâce à la contrainte imposé.

    Ceci dis, chacun à ses méthodes .
    On progresse .....

  7. #7
    mls
    mls est déconnecté
    Membre à l'essai
    Inscrit en
    Mai 2004
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 18
    Points : 13
    Points
    13
    Par défaut
    Citation Envoyé par Cl@udius Voir le message
    Salut



    Tu dois considérer cette valeur retournée comme un champ.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ...
    DT.DataSet.CommandText := 'INSERT INTO ma_table (ch1, ch2, ...) VALUES (:val1, :val2, ....) RETURNING ch1';
    ...
    DT.Execute;
    ID := DT.FieldByName('ch1').AsInteger;
    @+ Claudius
    En fait, j'y avais déjà pensé mais cela ne fonctionne pas. Une exception est générée comme quoi le champ "ch1" n'existe pas...

  8. #8
    Membre émérite
    Homme Profil pro
    Directeur technique
    Inscrit en
    Mai 2008
    Messages
    2 401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2008
    Messages : 2 401
    Points : 2 304
    Points
    2 304
    Par défaut
    Citation Envoyé par Andry Voir le message
    Généralement, ma clé primaire est juste un nombre sans signification particulier au niveau de ma table; dans la relation maitre/détail, la suppression est géré en cascade grâce à la contrainte imposé.

    Ceci dis, chacun à ses méthodes .
    c'est pour cela que je dis qu'il faut éviter
    Bon courage ou Bonne Chance (selon le contexte)
    Mon blog sur WordPress

  9. #9
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 038
    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 038
    Points : 40 943
    Points
    40 943
    Billets dans le blog
    62
    Par défaut
    un petit tour dans la FAQ de firebird (qui hélas reste au point mort depuis quelque temps, faute de volontaire)

    http://firebird.developpez.com/faq/i...ator#GEN_GETID

    donne le point de départ

    la réponse :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SELECT GEN_ID(GEN_MON_GENERATEUR,0) FROM 
    RDB$DATABASE;
    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

  10. #10
    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
    SergioMaster >>>
    Il faudra peut être incrémenter la valeur du générateur dans la requête et utiliser directement la valeur obtenue. Ceci pour éviter, les oublis d'incrémentation et les doublons en mode multi-utilisateur.
    mls >>>
    Tu lance cette requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SELECT GEN_ID(GEN_MON_GENERATEUR,1) FROM 
    RDB$DATABASE;
    Une fois que tu as cette valeur, tu peux l'affecter directement à tes champs pour les inserts.
    On progresse .....

  11. #11
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 038
    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 038
    Points : 40 943
    Points
    40 943
    Billets dans le blog
    62
    Par défaut
    @Andry
    en fait le 0 était bien intentionnel car si cette valeur est mise par Firebird lui même (dans un trigger par exemple) , je laisse imaginer la suite

    de plus Barbibulle l'explique bien je pense

    Quant a la question posée elle était
    J'aimerai récupérer cette valeur de l'auto increment lorsque je viens de l'ajouter dans la table.
    donc pas d'incrémentation a faire
    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

  12. #12
    mls
    mls est déconnecté
    Membre à l'essai
    Inscrit en
    Mai 2004
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 18
    Points : 13
    Points
    13
    Par défaut
    Bonjour, merci beaucoup pour toutes vos réponses apportées...

    En ce qui concerne le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT GEN_ID(GEN_MON_GENERATEUR,0) FROM 
    RDB$DATABASE
    j'ai peur qu'en mode multi-utilisateur, cela ne fonctionne pas à tous les coups si entre temps un utilisateur a eu le temps d'insérer un enregistrement dans la table (entre le INSERT et ce SELECT) .

    J'ai pense avoir trouvé une solution : comme je n'ai toujours pas trouvé comment récupérer (avec le composant TSimpleDataSet) une valeur, en l'occurence, l'auto-incrément venant d'être inséré avec cette syntaxe (comme indiqué dans mon premier message)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    INSERT INTO ..... VALUES ... RETURNING ch1
    j'ai utilisé exactement cette syntaxe avec en plus la syntaxe "INTO"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    INSERT INTO ..... VALUES ... RETURNING ch1 INTO :variable1
    mais à l'intérieur d'une procédure stockée, ce qui me permet de retourner la valeur de l'auto-incrément dans la variable de retour "variable1" que je peux lire avec cette fois-ci un TSQLStoredProc.

    Merci à tous d'avoir creusé vos neurones pour moi...
    @+

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

Discussions similaires

  1. récupérer la valeur d'un champ auto-incrémente
    Par mehdi.cheddani dans le forum VB.NET
    Réponses: 16
    Dernier message: 27/01/2014, 17h39
  2. Récupérer la valeur d'un champs auto incrémenté
    Par jim53 dans le forum Débuter
    Réponses: 2
    Dernier message: 06/12/2013, 21h49
  3. [PHP 5.3] Récupérer la valeur d'un champ auto-incrementé
    Par herve911 dans le forum Langage
    Réponses: 24
    Dernier message: 18/09/2011, 20h59
  4. [AC-2007] Comment récupérer la valeur du dernier numéro auto inséré dans une table ?
    Par marot_r dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 18/11/2010, 17h17
  5. Réponses: 1
    Dernier message: 20/07/2010, 12h28

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