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

PostgreSQL Discussion :

recuperer id SERIAL après INSERT INTO ?


Sujet :

PostgreSQL

  1. #1
    Futur Membre du Club
    Inscrit en
    Avril 2007
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 19
    Points : 8
    Points
    8
    Par défaut recuperer id SERIAL après INSERT INTO ?
    bonjour,
    j'ai une table avec un id SERIAL, sur un INSERT INTO (ajouter enregistrement) je ne specifie pas le champs de l'id je laisse le serveur s'en charger, ce qui se fait correctement avec le type SERIAL.
    problème :
    je voudrais après un tel INSERT recuperer l'id que le serveur vient d'attribué en sachant que les autres champs n'ont pas de contrainte UNIQUE et donc peuvent contenir des doublons.
    merci pour vos suggestions !

  2. #2
    Membre expérimenté Avatar de scheu
    Inscrit en
    Juin 2007
    Messages
    1 506
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 1 506
    Points : 1 734
    Points
    1 734
    Par défaut
    un type serial crée automatiquement une séquence sur la colonne, tu peux récupérer le curval de ta séquence (plus pratique que de faire un max(colonne) sur ta table)
    La théorie, c'est quand on sait tout mais que rien ne fonctionne.
    La pratique, c'est quand tout fonctionne mais que personne ne sait pourquoi.
    Ici, nous avons réuni théorie et pratique : Rien ne fonctionne ... et personne ne sait pourquoi !

    Réplication de base avec Postgresql : http://scheu.developpez.com/tutoriel.../log-shipping/

  3. #3
    Futur Membre du Club
    Inscrit en
    Avril 2007
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 19
    Points : 8
    Points
    8
    Par défaut
    et si jamais il y a une autre insertion à partir d'une autre machine sur le meme reseau avant que je ne recupere curval ... je ne recupere pas l'id de mon insertion mais celui d'une autre ?

  4. #4
    Membre expérimenté Avatar de scheu
    Inscrit en
    Juin 2007
    Messages
    1 506
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 1 506
    Points : 1 734
    Points
    1 734
    Par défaut
    c'est tout le problème du type serial quand il y a des insertions concurrentes
    le plus prudent c'est que, à chaque insertion, tu commences par récupérer le résultat de ta_sequence.nextval dans une variable, et c'est ce résultat que tu insères dans ta table via une 2ème requête
    ça évite le pb que tu décris
    La théorie, c'est quand on sait tout mais que rien ne fonctionne.
    La pratique, c'est quand tout fonctionne mais que personne ne sait pourquoi.
    Ici, nous avons réuni théorie et pratique : Rien ne fonctionne ... et personne ne sait pourquoi !

    Réplication de base avec Postgresql : http://scheu.developpez.com/tutoriel.../log-shipping/

  5. #5
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Citation Envoyé par hicpalm Voir le message
    et si jamais il y a une autre insertion à partir d'une autre machine sur le meme reseau avant que je ne recupere curval ... je ne recupere pas l'id de mon insertion mais celui d'une autre ?
    Non, tu récupèreras l'id de ton insertion, et pas celui d'une autre session. Cela permet d'utiliser la valeur renvoyée par nextval() comme clé étrangère valide dans d'autres tables "esclaves" après l'insertion dans la table "maître". Le corollaire est que l'incrémentation des numéros de séquence n'est pas réversible (un Rollback d'une transaction comprenant un nextval() ne décrementera pas la séquence).

    Pour plus d'information, voir l'article de Damien : http://dgriessinger.developpez.com/p...sql/sequences/
    FAQ XML
    ------------
    « Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
    Giacomo Leopardi

  6. #6
    Futur Membre du Club
    Inscrit en
    Avril 2007
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 19
    Points : 8
    Points
    8
    Par défaut
    ok ... il est bon le truc des sequences, ça resout pas mal de problèmes !
    merci pour votre temps et suggestions !

  7. #7
    Membre averti Avatar de icer
    Inscrit en
    Janvier 2006
    Messages
    332
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 332
    Points : 363
    Points
    363
    Par défaut
    le plus prudent c'est que, à chaque insertion, tu commences par récupérer le résultat de ta_sequence.nextval dans une variable, et c'est ce résultat que tu insères dans ta table via une 2ème requête
    ça évite le pb que tu décris
    Ceci ne résoud pas le problème : il peut trés bien y avoir une insertion depuis une autre session entre la lecture de ta_sequence.nextval et le nouvel insert.

    Une solution serait de poser un verrou sur la table avant l'insertion et de le relacher aprés avoir récupérer la valeur de la séquence. Ainsi, la valeur de la sequence sera obligatoirement celle de la derniére insertion. Puisqu'il était impossible d'inserer d'autre ligne entre temps grace au verrou.

  8. #8
    Futur Membre du Club
    Inscrit en
    Avril 2007
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 19
    Points : 8
    Points
    8
    Par défaut
    Ceci ne résoud pas le problème : il peut trés bien y avoir une insertion depuis une autre session entre la lecture de ta_sequence.nextval et le nouvel insert.
    ce qui j'ai cru comprendre de la réponse de "scheu" c'est qu'on récupérant une nextval() cette valeur ne sera plus attribué par la suite pour une autre session concurente, et c'est cette valeur que j'utilise pour insert en spécifiant explicitement l'id par la valeur retournée precedement par nextval (je n'insert pas avec un id par defaut )... et avec ceci pas besoin de verrou ? ... à moins que le serveur n'interdise l'insertion avec un id dépassé par la sequence meme s'il n'est pas réellement dans la table : c'est le cas ?

  9. #9
    Membre averti Avatar de icer
    Inscrit en
    Janvier 2006
    Messages
    332
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 332
    Points : 363
    Points
    363
    Par défaut
    Désolé, je me suis trompé.

    En lisant trop vite ce thread, j'ai ne pas pris connaissance du fait suivant :
    Le corollaire est que l'incrémentation des numéros de séquence n'est pas réversible (un Rollback d'une transaction comprenant un nextval() ne décrementera pas la séquence)
    La solution de "scheu" est bien correct, je l'ai testé.

    Tu peux donc faire tes inserts tranquillement.

  10. #10
    Futur Membre du Club
    Inscrit en
    Avril 2007
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 19
    Points : 8
    Points
    8
    Par défaut
    ok ! merci à tous !

  11. #11
    Membre expérimenté Avatar de scheu
    Inscrit en
    Juin 2007
    Messages
    1 506
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 1 506
    Points : 1 734
    Points
    1 734
    Par défaut
    C'est tout l'intérêt du nextval : tu récupères une bonne fois pour toutes une valeur unique qui ne sera plus jamais utilisée, donc si côté développement c'est possible de faire en 2 étapes (d'abord récupérer le nextval et ensuite insérer), c'est plus propre que de poser temporairement un verrou sur ta table
    La théorie, c'est quand on sait tout mais que rien ne fonctionne.
    La pratique, c'est quand tout fonctionne mais que personne ne sait pourquoi.
    Ici, nous avons réuni théorie et pratique : Rien ne fonctionne ... et personne ne sait pourquoi !

    Réplication de base avec Postgresql : http://scheu.developpez.com/tutoriel.../log-shipping/

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

Discussions similaires

  1. Recuperer l'identifiant aprés insertion d'un tupple
    Par bambou dans le forum PostgreSQL
    Réponses: 17
    Dernier message: 01/10/2010, 15h29
  2. recuperer Sequence Oracle après insert
    Par maxf1 dans le forum JDBC
    Réponses: 3
    Dernier message: 10/02/2007, 23h17
  3. la commande insert into et le type serial
    Par nael_n dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 28/08/2006, 11h16
  4. Réponses: 11
    Dernier message: 26/07/2006, 14h35
  5. comment recuperer l'id apres un insert
    Par philippe123 dans le forum ASP
    Réponses: 5
    Dernier message: 09/08/2005, 09h54

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