Précédent   Forum des professionnels en informatique > Bases de données > PostgreSQL
PostgreSQL Forum PostgreSQL. Avant de poster -> F.A.Q PostGreSQL Tutoriels PostGreSQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 30/01/2008, 08h22   #1
Invité de passage
 
Inscription : avril 2007
Messages : 19
Détails du profil
Informations forums :
Inscription : avril 2007
Messages : 19
Points : 1
Points : 1
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 !
hicpalm est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/01/2008, 13h52   #2
Membre Expert
 
Avatar de scheu
 
Inscription : juin 2007
Messages : 1 497
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 1 497
Points : 1 483
Points : 1 483
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)
scheu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/01/2008, 08h28   #3
Invité de passage
 
Inscription : avril 2007
Messages : 19
Détails du profil
Informations forums :
Inscription : avril 2007
Messages : 19
Points : 1
Points : 1
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 ?
hicpalm est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/01/2008, 09h53   #4
Membre Expert
 
Avatar de scheu
 
Inscription : juin 2007
Messages : 1 497
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 1 497
Points : 1 483
Points : 1 483
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
scheu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/01/2008, 14h24   #5
Expert Confirmé Sénior
 
Avatar de GrandFather
 
Inscription : mai 2004
Messages : 4 490
Détails du profil
Informations personnelles :
Âge : 42

Informations forums :
Inscription : mai 2004
Messages : 4 490
Points : 5 049
Points : 5 049
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
GrandFather est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/02/2008, 08h10   #6
Invité de passage
 
Inscription : avril 2007
Messages : 19
Détails du profil
Informations forums :
Inscription : avril 2007
Messages : 19
Points : 1
Points : 1
ok ... il est bon le truc des sequences, ça resout pas mal de problèmes !
merci pour votre temps et suggestions !
hicpalm est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/02/2008, 13h32   #7
Membre éclairé
 
Avatar de icer
 
Inscription : janvier 2006
Messages : 332
Détails du profil
Informations forums :
Inscription : janvier 2006
Messages : 332
Points : 308
Points : 308
Citation:
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.
icer est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/02/2008, 07h38   #8
Invité de passage
 
Inscription : avril 2007
Messages : 19
Détails du profil
Informations forums :
Inscription : avril 2007
Messages : 19
Points : 1
Points : 1
Citation:
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 ?
hicpalm est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2008, 14h20   #9
Membre éclairé
 
Avatar de icer
 
Inscription : janvier 2006
Messages : 332
Détails du profil
Informations forums :
Inscription : janvier 2006
Messages : 332
Points : 308
Points : 308
Désolé, je me suis trompé.

En lisant trop vite ce thread, j'ai ne pas pris connaissance du fait suivant :
Citation:
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.
icer est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/02/2008, 09h45   #10
Invité de passage
 
Inscription : avril 2007
Messages : 19
Détails du profil
Informations forums :
Inscription : avril 2007
Messages : 19
Points : 1
Points : 1
ok ! merci à tous !
hicpalm est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/02/2008, 09h46   #11
Membre Expert
 
Avatar de scheu
 
Inscription : juin 2007
Messages : 1 497
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 1 497
Points : 1 483
Points : 1 483
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
scheu est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 13h09.


 
 
 
 
Partenaires

Hébergement Web