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 :

Gérer une FK pointant sur une PK de type SERIAL [9.1]


Sujet :

PostgreSQL

  1. #1
    Membre à l'essai
    Femme Profil pro
    Ingénieure novice !
    Inscrit en
    Juin 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Femme

    Informations professionnelles :
    Activité : Ingénieure novice !
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2012
    Messages : 21
    Points : 10
    Points
    10
    Par défaut Gérer une FK pointant sur une PK de type SERIAL
    Bonjour à tous !

    Je m'en remets à vous, car malgré mes recherches, je reste bloquée face à un problème de clé étrangère pointant sur une clé primaire de type SERIAL !

    En fait voilà, rien ne vaut un exemple simplifié :

    J'ai une table projet dont la clé primaire id_projet est de type SERIAL.
    J'ai une table objet dont la clé primaire id_objet est de type SERIAL.
    Un projet contient plusieurs objets.
    Un objet peut appartenir à 1 ou plusieurs projets, ainsi j'ai une table supplémentaire Fait_partie_projet dont la clé primaire est faite de deux clés étrangères :
    id_projet INTEGER REFERENCES projet (id_projet)
    et :
    id_objet INTEGER REFERENCES objet (id_objet)

    Je connais la fonction currval() pour utiliser la valeur actuelle d'une séquence.
    Le fait est qu'il est tout à fait possible d'insérer un premier tuple dans projet, pour un projet x par exemple. Ensuite, de commencer à remplir les tables objet et fait_partie_projet dans lesquelles en effet je peux utiliser currval() pour récupérer la clé primaire de ma table projet. Mais ensuite, si un nouveau projet y est déclaré, faisant incrémenter la clé primaire, comment faire référence au projet x (ou n'importe quel autre projet inséré auparavant) dans ma table fait_partie_projet ?!
    J'ai bien pensé aussi à faire une fonction (en tant que débutante ceci est un peu obscure pour moi cependant) en utilisant un "RETURNING (id_projet) AS monprojet" mais je me suis dit que le problème serait le même : Si j'insère un nouveau projet, la variable monprojet contiendra alors la nouvelle valeur de clé primaire... Et donc comment faire référence à d'anciennes clés primaires....

    Bref, au secours !
    N'hésitez pas à me demander des précisions si je n'ai pas été claire !
    Merci par avance à ceux qui me liront et prendront le temps de m'aiguiller !

  2. #2
    Membre expert
    Avatar de alassanediakite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Mali

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 1 599
    Points : 3 590
    Points
    3 590
    Billets dans le blog
    8
    Par défaut
    Salut
    Par quelle interface (outil d'admin ou langage de programmation) tu manipules les données?
    @+
    Le monde est trop bien programmé pour être l’œuvre du hasard…
    Mon produit pour la gestion d'école: www.logicoles.com

  3. #3
    Membre à l'essai
    Femme Profil pro
    Ingénieure novice !
    Inscrit en
    Juin 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Femme

    Informations professionnelles :
    Activité : Ingénieure novice !
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2012
    Messages : 21
    Points : 10
    Points
    10
    Par défaut
    Salut alassanediakite,

    A terme je manipulerai les données via php (car je créé une interface web dont les données saisies par l'utilisateur, via formulaires, seront récupérées et manipulées), mais pour l'instant j'essaie de comprendre comment tout cela fonctionne simplement en interagissant avec ma base de données via le terminal, je n'utilise pas d'outil d'administration.

  4. #4
    Membre expert
    Avatar de alassanediakite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Mali

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 1 599
    Points : 3 590
    Points
    3 590
    Billets dans le blog
    8
    Par défaut
    Salut
    Les outils pour lignes de commandes ne sont vraiment pas fait pour ça!!! Ces genres de traitements se font avec des IHM graphiques.
    @+
    Le monde est trop bien programmé pour être l’œuvre du hasard…
    Mon produit pour la gestion d'école: www.logicoles.com

  5. #5
    Membre à l'essai
    Femme Profil pro
    Ingénieure novice !
    Inscrit en
    Juin 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Femme

    Informations professionnelles :
    Activité : Ingénieure novice !
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2012
    Messages : 21
    Points : 10
    Points
    10
    Par défaut
    Alors il n'est pas possible de s'en sortir avec le type SERIAL lorsqu'on interagit avec sa base de données via le terminal, sans aucun intermédiaire ? Il faut obligatoirement passer par une interface ?

    Entre temps j'ai essayé d'adapter mon interface web (elle existait déjà, mais avant les clés primaires étaient des varchar à saisir manuellement sur l'interface, oui c'est moche ), et j'arrive à m'en sortir en récupérant l'ensemble des projets (clé primaire + leur nom) et en les proposant dans un <select>. Ainsi l'utilisateur repère son projet grâce à son nom, et quand il le sélectionne je récupère la clé primaire qui va avec grâce à l'attribut value. Plus besoin de passer par currval() ou autre. Donc en effet je m'en sors mieux ainsi, mais j'aurais aimé savoir comment s'en dépatouiller sans interface...
    Dommage qu'apparemment ce ne soit pas possible ! Si quelqu'un d'autre a une astuce je suis toujours preneuse
    Quoiqu'il en soit merci pour ta rapide réponse alassanediakite !

  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    En résumant fortement ta question je retiens ça:
    "s'il n'y a que currval() pour rappeler la dernière valeur d'une séquence mais que j'ai besoin de rappeler plusieurs valeurs, comment faire?"

    La solution est de stocker les valeurs dans des variables. Et au passage pour ce faire, RETURNING est la meilleure méthode, même si currval() marche aussi.

    Le problème n'est pas d'utiliser une interface graphique ou pas, c'est juste que quand on a besoin de lancer plusieurs requêtes et de traiter les résultats entre les deux, il faut faire un programme procédural, en php ou autre, qui ordonne tout ça et utilise des variables pour les résultats intermédiaires. Alors que "à la main" en mode terminal on n'a pas de variables.

  7. #7
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 496
    Points : 12 596
    Points
    12 596
    Par défaut
    Il me semble que vous l'embrouiller un peu plus.
    Ce qu'elle demande nous le faisons tous jours.

    Il est bien évident qu'elle ne va pas créer 500 projets et 40000 objets dans les 10 secondes.

    Elle à modéliser ses tables, bien.
    Lui reste à faire ses interfaces.

    Un menu reprenant ses projets, une fois celui-ci sélectionné on dispose de son id ensuite on insère les ojbjet et puis si on crée un nouveau projet pas de souci.

    Pas besoin ici de curval() ou returning(), une simple interface de de gestion quoi !

  8. #8
    Membre à l'essai
    Femme Profil pro
    Ingénieure novice !
    Inscrit en
    Juin 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Femme

    Informations professionnelles :
    Activité : Ingénieure novice !
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2012
    Messages : 21
    Points : 10
    Points
    10
    Par défaut
    Bonjour et merci pour vos réponses estofilo et MaitrePylos !

    J'avais en effet déjà pensé à utiliser RETURNING(), qui ne s'utilise qu'au sein de fonctions n'est-ce pas ? Mais si je déclare une fonction qui insère un nouveau projet et retourne la valeur de la clé primaire dans une variable, lors de l'insertion d'un autre projet, il me semble que la variable prendra la valeur de la nouvelle clé primaire incrémentée, et du coup j'aurais le même problème ? Je n'ai jamais eu à faire à des fonctions SQL il y a peut être quelque chose qui m'échappe !

    MaitrePylos, en effet comme je l'ai dit dans mon dernier message, depuis que je passe par mon interface web je me débrouille très bien, en faisant sélectionner le projet via un menu déroulant, ainsi je récupère la clé primaire associée et zou c'est parti ! :-)
    Je pensais simplement qu'il y avait une astuce pour s'en sortir via le terminal directement, car pour moi la base de données elle-même et l'interface pour interagir plus facilement avec elle sont deux choses distinctes et l'on peut très bien utiliser une base de données sans lui construire d'interface. Probablement grâce au RETURNING() que mentionne estofilo ^^

    Merci à vous et bonne journée !

  9. #9
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Le RETURNING est une clause liée à un INSERT, ça n'a pas de rapport avec les fonctions.

    Par exemple:

    test=> CREATE TABLE exemple(id SERIAL, nom TEXT);
    
    NOTICE:  CREATE TABLE will create implicit sequence "exemple_id_seq" for serial column "exemple.id"
    CREATE TABLE
    
    test=> INSERT INTO exemple(nom) VALUES('le nom') RETURNING id;
     id 
    ----
      1
    (1 row)
    
    INSERT 0 1
    
    L'insert renvoie directement la valeur insérée pour id (ici 1) sans besoin de currval().

  10. #10
    Membre à l'essai
    Femme Profil pro
    Ingénieure novice !
    Inscrit en
    Juin 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Femme

    Informations professionnelles :
    Activité : Ingénieure novice !
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2012
    Messages : 21
    Points : 10
    Points
    10
    Par défaut
    D'accord , j'avais pas mal compris le fonctionnement de RETURNING(), je croyais que cela créait une nouvelle variable, en fait non cela retourne une valeur d'un attribut existant
    Merci pour cet exemple !

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

Discussions similaires

  1. Pb sur une requête DELETE sur une chaine
    Par astrolane dans le forum Sybase
    Réponses: 4
    Dernier message: 16/02/2009, 10h11
  2. Réponses: 9
    Dernier message: 07/02/2008, 17h42
  3. Réponses: 3
    Dernier message: 25/10/2007, 12h47
  4. initialiser une struc pointant sur une struct
    Par gronaze dans le forum C
    Réponses: 5
    Dernier message: 30/03/2006, 17h07

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