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 l'identifiant aprés insertion d'un tupple


Sujet :

PostgreSQL

  1. #1
    Membre du Club Avatar de bambou
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mars 2004
    Messages : 192
    Points : 69
    Points
    69
    Par défaut Recuperer l'identifiant aprés insertion d'un tupple
    Bonjour,

    Je vien du forum PHP ou on m'a renvoyé par ici..

    Est-ce que quelqu'un saurait si il existe une fonction equivalente à MySQL mysql_insert_id() pour postgres?

    à savoir qui retournerai l'identifiant d'un tupple que l'on vient d'inserer sans avoir a passer une nouvelle requete?

    merci


    ps : le post relatif dans le forum php

  2. #2
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 016
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 016
    Points : 23 705
    Points
    23 705
    Par défaut
    Bonjour,
    Dans Postgres, je ne crois pas qu'il y ait de fonction d'auto incrément comme dans MySQL. Les clefs peuvent être générées par des séquences.
    Donc, si tu as le nom de l'objet séquence utilisé sur ta table, l'instruction currval('nom_sequence') renvoit la dernière valeur employée par cette séquence.

    ced
    Rédacteur / Modérateur SGBD et R
    Mes tutoriels et la FAQ MySQL

    ----------------------------------------------------
    Pensez aux balises code et au tag
    Une réponse vous a plu ? N'hésitez pas à y mettre un
    Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça

  3. #3
    Membre du Club Avatar de bambou
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mars 2004
    Messages : 192
    Points : 69
    Points
    69
    Par défaut
    l'instruction currval('nom_sequence') est une instruction SQL non?

    Si je veux l'utiliser il faut que je fasse une requete SQL..ça revient plus ou moin au meme que de refaire un select

  4. #4
    Membre expérimenté

    Inscrit en
    Mai 2002
    Messages
    720
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 720
    Points : 1 594
    Points
    1 594
    Par défaut
    Salut

    ced, ta méthode peut poser problème car l'INSERT et le SELECT qui suit ne sont pas effectués de façon atomique. Si une nouvelle ligne est insérée dans la table entre les deux instructions, le SELECT renverra la mauvaise valeur.

    Il ne reste que deux solutions:
    • Faire un SELECT en cherchant les valeurs qui viennent d'être insérées. Si ces valeurs sont uniques, pas de problème, sinon on peut avoir plusieurs lignes de résultat et là c'est un autre problème.
    • Utiliser l'extension non-standard de PostgreSQL 8.2+ RETURNING documentée ici : http://www.postgresql.org/docs/8.2/i...ql-insert.html

    Smortex

    Les FAQ Assembleur - Linux
    In The Beginning Was The Command Line Neal Stephenson

  5. #5
    Membre habitué Avatar de budtucker
    Profil pro
    Développeur multimédia
    Inscrit en
    Avril 2007
    Messages
    176
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur multimédia

    Informations forums :
    Inscription : Avril 2007
    Messages : 176
    Points : 197
    Points
    197
    Par défaut
    Smortex, de spéculer qu'un insert puisse se produire entre un insert et un select (surtout sur une séquence) est un peu (beaucoup !!) improbable. A part si on bosse sur une application d'environ une centaine d'accès à la seconde !! Je crois que seul SourceForge.com peut se vanter de ça.

    Bien sûr, comme tu l'as indiqué, on peut également utiliser la forme suivante :

    J'ai une table jour avec id_jour en serial :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    INSERT INTO jour(
                 madate, lib_jourferie)
        VALUES ( now(), 'aujourdhui') RETURNING id_jour;
    A+
    Sud04

  6. #6
    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 Smortex
    ced, ta méthode peut poser problème car l'INSERT et le SELECT qui suit ne sont pas effectués de façon atomique. Si une nouvelle ligne est insérée dans la table entre les deux instructions, le SELECT renverra la mauvaise valeur.
    L'INSERT et le SELECT ne sont effectivement pas atomiques, mais en l'occurrence cela n'a pas d'importance car currval() renverra le dernier numéro "consommé" dans la même session. Même si des sessions ouvertes par d'autres clients insèrent d'autres enregistrements entre l'INSERT et le SELECT, la cohérence de la valeur renvoyée par currval() est garantie pour la session qui l'appelle. Seule contrainte, il faut impérativement qu'un nextval() ait été appelé auparavant dans la même session, ce qui est le cas ici puisque l'insertion d'un enregistrement comportant un champ du type SERIAL déclenche automatiquement l'appel de cette fonction.

    budtucker >> compter sur la chance pour que la base conserve son intégrité est s'exposer tôt ou tard à un rappel douloureux de la Loi de Murphy...
    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

  7. #7
    Membre du Club Avatar de bambou
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mars 2004
    Messages : 192
    Points : 69
    Points
    69
    Par défaut
    Merci beaucoup pour toutes ces réponses,

    je vais voir si il est possible de mettre en place l'extension returning sur la BD que j'utilise, ce serait l'ideal

    encore merci a vous tous

  8. #8
    jnore
    Invité(e)
    Par défaut
    L'aggrégat 'RETURNING' est vraiment intéressant. Le problème est si l'on veut migrer vers un autre SGBD, ça ne sera pas interprété !!
    La ou les requetes seront bonnes à refaire!

  9. #9
    Membre du Club Avatar de bambou
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mars 2004
    Messages : 192
    Points : 69
    Points
    69
    Par défaut
    dans mon cas précis ça ne pose pas de probleme il est possible qu'il y ait migration des données vers une autre architecture de la base, mais le moteur restera posgres, donc le returning me convient parfaitement

  10. #10
    Membre expérimenté
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2004
    Messages
    374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 374
    Points : 1 401
    Points
    1 401
    Par défaut
    Euh est-ce que la fonction nextval() ne sert pas précisément à ce genre de situation ?

    Je veux dire: On commence par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT nextval('sequence');
    puis:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    INSERT INTO table ( id, col2, col3, ... ) VALUES ( [résultat de la requête du dessus], val2, val3, ... );
    Enfin moi c'est comme ça que je fais ^^ Pas d'extension supplémentaire nécessaire, on est absolument certain de ne pas "mélanger" les id, c'est simple, beau, rapide, cool, bien, chouette ^^

    Dites moi si je me trompe svp

  11. #11
    Membre du Club Avatar de bambou
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mars 2004
    Messages : 192
    Points : 69
    Points
    69
    Par défaut
    Pour recadrer un peu les choses : mon but était d'essayer de diminuer le nombre de requetes, passer de 3 à 2 :
    - Un select pour vérifier l'existance du tupple
    - Un insert pour inserer le tupple
    - Un select pour récupérer l'identifiant

    pour la derniere requete que je fasse un select classique ou un SELECT NEXTVAL('sequence');, cela ne change rien, j'ai toujours 3 requetes...

    ...alors qu'avec le returning, la 3eme requete n'est plus nécessaire.

    J'aurais été en php5 j'aurais pu tout faire avec une seule requete, mais malheuresement ce n'est pas le cas :'(

  12. #12
    Membre expérimenté
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2004
    Messages
    374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 374
    Points : 1 401
    Points
    1 401
    Par défaut
    En effet ça ne change rien du point de vue du nombre de requêtes, j'avais pas compris le débat désolé

  13. #13
    Membre expérimenté

    Inscrit en
    Mai 2002
    Messages
    720
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 720
    Points : 1 594
    Points
    1 594
    Par défaut
    Citation Envoyé par Shepard
    Euh est-ce que la fonction nextval() ne sert pas précisément à ce genre de situation ?

    [couic]
    C'est moins lourd que de refaire une sélection sur tous les champs après, et comme le champ est indexé, la recherche est simplifiée. Tu perds juste la flexibilité offerte en mettant une valeur par défaut pour ce champ et le laisser gérer par PostgreSQL. Donc si tu es dans une situation telle que celle décrite par GrandFather, je pense qu'il est encore plus simple de faire un SELECT sur currval() après l'insertion.

    Citation Envoyé par bambou
    J'aurais été en php5 j'aurais pu tout faire avec une seule requete, mais malheuresement ce n'est pas le cas :'(
    Il me semblais que le moteur magique qui accède à la base de données en exécutant seulement une requète sur deux est prévu dans PHP 7.0 seulement (Les goto de PHP 6.0 étants requis pour implémenter cette extension)...

    Smortex

    Les FAQ Assembleur - Linux
    In The Beginning Was The Command Line Neal Stephenson

  14. #14
    Membre du Club Avatar de bambou
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mars 2004
    Messages : 192
    Points : 69
    Points
    69
    Par défaut
    Citation Envoyé par Smortex
    Il me semblais que le moteur magique qui accède à la base de données en exécutant seulement une requète sur deux est prévu dans PHP 7.0 seulement (Les goto de PHP 6.0 étants requis pour implémenter cette extension)...
    rhooo c'est pas gentil de ce moquer des noobs qui s'exprime mal!! vilain canaillou va

    non ce que j'entendais par par
    J'aurais été en php5 j'aurais pu tout faire avec une seule requete, mais malheuresement ce n'est pas le cas :'(
    c'est qu'avec un try/catch...imlémenté dans php5...j'aurais pu faire l'insert directement et récupérer l'erreur, si erreur il y avait. le 'tout' désignait les 2 premieres requetes (a savoir, rechercher l'existance du tupple et l'inserer si il n'existe pas), ce qui effectivement n'était pas trés bien formulé, je le reconnais

    mais au final 2 requetes sont nécessaires, on est d'accord

  15. #15
    Membre émérite
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Points : 2 677
    Points
    2 677
    Par défaut
    Bonjour !

    Je me permets de faire remonter le sujet, car il n'a pas vraiment été apporté de réponse à la question initiale (dont la réponse m'intéresse (si si si sans déconner )) :

    Citation Envoyé par bambou Voir le message
    Est-ce que quelqu'un saurait si il existe une fonction equivalente à MySQL mysql_insert_id() pour postgres?
    Dans mon cas je dispose du PGresult * renvoyé par la dernière requête passée et forcément du PGconn * de ma connexion.

    S'il n'y a toujours pas d'autres moyens que ceux énoncés dans ce topic, je me résignerai, la mort dans l'âme, à truander

    Merci d'avance.
    Vous postez du code ? Merci d'utiliser les balises
    Un message vous paraît pertinent ? Merci de le gratifier d'un vote positif
    Vous avez obtenu une réponse à votre question ? Merci d'utiliser le tag
    __________________
    Ingénieur R&D, diplômé en 2007 de l'ISIMA
    Docteur en informatique, diplômé en 2015 de l'EDSPI de Clermont-Ferrand

  16. #16
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 761
    Points : 52 547
    Points
    52 547
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par bambou Voir le message
    Pour recadrer un peu les choses : mon but était d'essayer de diminuer le nombre de requetes, passer de 3 à 2 :
    - Un select pour vérifier l'existance du tupple
    - Un insert pour inserer le tupple
    - Un select pour récupérer l'identifiant
    Là vous faites fausse route complète !!!!

    1) entre la requête 1 et la 2 les données peuvent changer du fait des actions concurrentes des utilisateurs. Le risque est donc énorme d'obtenir une incohérence de la base de données tôt ou tard.... et je vous renvoie sur le commentaire précédent : http://www.developpez.net/forums/d36...e/#post2256364 (loi de Murphy)

    Le plus simple est d'incorporer la requête 1 dans la 2. Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INSERT INTO MaTable
    WHERE ...
    Ensuite compter le nombre de ligne insérées... ceci est faisable pour toute requête du côté client, comme du côté serveur !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    DECLARE  
       nb_lignes integer;  
    BEGIN  
       INSERT INTO ...
       GET DIAGNOSTICS nb_lignes := ROW_COUNT;  
       IF nb_lignes  = 0 ...
    2) diminuer le nombre de requête n'est pas une fin en soi. Ce qui importe dans un SGBDR est de diminuer les temps de verrouillage d'un côté (serveur) et les aller retours de l'autre côté (client).
    Dans ce sens l'utilisation des procédures stockées (Dans PostGreSQL ce sont des fonctions) ne peut que vous apporter des bienfaits et répondre aux deux problématiques....

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  17. #17
    Membre émérite
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Points : 2 677
    Points
    2 677
    Par défaut
    Pour répondre à la question initiale, je crois que la requête suivante doit renvoyé le résultat souhaité :
    Vous postez du code ? Merci d'utiliser les balises
    Un message vous paraît pertinent ? Merci de le gratifier d'un vote positif
    Vous avez obtenu une réponse à votre question ? Merci d'utiliser le tag
    __________________
    Ingénieur R&D, diplômé en 2007 de l'ISIMA
    Docteur en informatique, diplômé en 2015 de l'EDSPI de Clermont-Ferrand

  18. #18
    Membre émérite
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Points : 2 677
    Points
    2 677
    Par défaut
    Je repasse en coup de vent pour confirmer que cette requête retourne effectivement le résultat souhaité
    Vous postez du code ? Merci d'utiliser les balises
    Un message vous paraît pertinent ? Merci de le gratifier d'un vote positif
    Vous avez obtenu une réponse à votre question ? Merci d'utiliser le tag
    __________________
    Ingénieur R&D, diplômé en 2007 de l'ISIMA
    Docteur en informatique, diplômé en 2015 de l'EDSPI de Clermont-Ferrand

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

Discussions similaires

  1. recuperation de l'identifiant après insertion
    Par al-faddi dans le forum C#
    Réponses: 3
    Dernier message: 28/05/2015, 19h24
  2. Réponses: 5
    Dernier message: 30/07/2010, 20h33
  3. recuperer id SERIAL après INSERT INTO ?
    Par hicpalm dans le forum PostgreSQL
    Réponses: 10
    Dernier message: 11/02/2008, 09h46
  4. recuperer Sequence Oracle après insert
    Par maxf1 dans le forum JDBC
    Réponses: 3
    Dernier message: 10/02/2007, 23h17
  5. Réponses: 11
    Dernier message: 26/07/2006, 14h35

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