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

MySQL Discussion :

Impossible d'ajouter une clé étrangére composée d'une paire d'attributs


Sujet :

MySQL

  1. #1
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    226
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 226
    Points : 119
    Points
    119
    Par défaut Impossible d'ajouter une clé étrangére composée d'une paire d'attributs
    Bonjour,
    Il y a assez longtemps, on m'avait aidé a mettre en place une architecture où dans une des tables de la BDD, la clé primaire était composée de la paire {clé étrangére d'une table , une colone}. (http://www.developpez.net/forums/d15...e-associative/)
    Je souhaiterais remettre en place cette base mais je rencontre un probléme.
    Pour l'instant, j'ai déjà ces tables en BDD
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    CREATE TABLE FOUR 
    (
        id_four INT(11) NOT NULL,
        nom VARCHAR(25)  NOT NULL,
        CONSTRAINT PRIMARY KEY (id_four)
    ) ;
     
    CREATE TABLE FOUR_CYCLES
    (
        id_four INT(11) NOT NULL,
        no_cycle VARCHAR(2) NOT NULL,
        CONSTRAINT PRIMARY KEY (id_four, no_cycle),
        CONSTRAINT FOUR_CYCLE_FOUR_FK FOREIGN KEY (FourId)
        REFERENCES FOUR (FourId)
        ON DELETE CASCADE
    ) ;
     
    CREATE TABLE GATEAUX
    (        
        id_gateau INT(11) NOT NULL,
        nom VARCHAR(25) NOT NULL,
        id_four INT(11) NOT NULL,
        no_cycle VARCHAR(2) NOT NULL,
        CONSTRAINT GATEAU PRIMARY KEY (GateauId)
    )
    Je souhaiterais mettre en place la clé primaire de la table FOUR_CYCLES en clé étrangére dans la table GATEAUX mais c'est là que je rencontre un probléme...
    Je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    ALTER TABLE GATEAUX
    ADD FOREIGN KEY (id_four, no_cycle)
    REFERENCES FOUR_CYCLES(id_four, no_cycle)
    ON DELETE CASCADE
    Et j'obtiens ce message : "#1452 - Cannot add or update a child row: a foreign key constraint fails".

    Quelqu'un sait pourquoi j'obtient ce message et je n'arrive pas ajouter ma clé étrangére?

    Merci.

  2. #2
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    226
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 226
    Points : 119
    Points
    119
    Par défaut
    J'ai un peu triché en faisant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SET FOREIGN_KEY_CHECKS = 0;
    avant l'ajout de la clé étrangére.

    Quand je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SHOW CREATE TABLE `GATEAUX`
    j'ai
    UNIQUE KEY `id_four` (`id_four`,`no_cycle`),
    CONSTRAINT `GATEAUX_ibfk_7` FOREIGN KEY (`id_four`, `no_cycle`) REFERENCES `FOUR_CYCLES` (`id_four`, `no_cycle`) ON DELETE CASCADE

    Peut-on considérer que c'est OK? Ou il ne faut pas procéder comme ça?

  3. #3
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    Comme l'indique le message d'erreur, vous ne pouvez poser la contrainte car les données présentes dans les tables ne la respectent pas (il existe au moins une clef dans la table gateau absente de la table four_cycle).

    corrigez vos données et tout devrait rentrer dans l'ordre.

  4. #4
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 909
    Points
    38 909
    Billets dans le blog
    9
    Par défaut
    Bonjour,

    Il y a des choses qui ne vont pas dans votre DDL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TABLE GATEAUX
    (        
        id_gateau INT(11) NOT NULL,
        nom VARCHAR(25) NOT NULL,
        id_four INT(11) NOT NULL,
        no_cycle VARCHAR(2) NOT NULL,
        CONSTRAINT GATEAU PRIMARY KEY (GateauId)
    )
    De plus, c'est une mauvaise idée de mettre une colonne de type varchar en clef, a priori il s'agit d'un numéro, utilisez donc un smallint ce sera plus performant
    En plus varchar(2) n'a aucun intérêt car plus long que du char(2), moins pratique, et moins performant.
    Modif à faire sur four et gâteaux bien sur (varchar ==> smallint)

  5. #5
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    226
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 226
    Points : 119
    Points
    119
    Par défaut
    Bonjour et merci pour votre réponse

    J'ai pourtant bien vérifié.
    Avec SHOW CREATE TABLE sur les 2 tables, j'ai bien les mêmes données (même nom, même type)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    CREATE TABLE `FOUR_CYCLES` (
     `id_four` int(11) NOT NULL,
     `no_cycle` varchar(2) NOT NULL,
     PRIMARY KEY (`id_four`,`no_cycle`),
     UNIQUE KEY `id_four` (`id_four`,`no_cycle`),
     CONSTRAINT `FOUR_CYCLES_ibfk_1` FOREIGN KEY (`id_four`) REFERENCES `FOUR` (`id_four`) ON DELETE CASCADE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8
     
    CREATE TABLE `GATEAUX` (
    `id_gateau` int(11) NOT NULL,
    'nom' varchar(2) NOT NULL,
    `id_four` int(11) NOT NULL,
    `no_cycle` varchar(2) NOT NULL,
    PRIMARY KEY (`id_gateau`),
    UNIQUE KEY `id_reacteur` (`id_reacteur`,`no_cycle`),
    CONSTRAINT `GATEAUX_ibfk_7` FOREIGN KEY (`id_four`, `no_cycle`) REFERENCES `FOUR_CYCLES` (`id_four`, `no_cycle`) ON DELETE CASCADE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8

  6. #6
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 909
    Points
    38 909
    Billets dans le blog
    9
    Par défaut
    Ce DDL n'est pas le même que celui de votre 1er post !
    Quoi qu'il en soit, pour pouvoir ajouter une contrainte après chargement de votre table, il faut que le contenu de cette table satisfasse la contrainte.
    Vous pouvez vérifier par la requête suivante, les lignes qui ne satisfont pas la contrainte :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    select * from gateaux T1
    where not exists
         (select 1 
          from FOUR_CYCLES T2
          where T2.id_four  = T1.id_four 
            and T2.no_cycle = T1.no_cycle)
    Et si possible, modifiez la colonne no_cycle dans les 2 tables pour la mettre en smallint

    EDIT : Je remarque aussi que dans votre 1er post, vous avez la même erreur entre la table four et cycle : id_four et four_id

  7. #7
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    226
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 226
    Points : 119
    Points
    119
    Par défaut
    Bonjour à vous désolé je n'avais pas vu votre message précédent.
    Si j'ai bien compris, si le petit code que vous avez mis me retourne un résultat, ce serait à cause de ce dernier que je ne pouvait pas ajouter ma clé étrangére?
    Je vais modifier no_cycle, par contre il peut contenir une lettre, c'est pour ça que j'avais mis VARCHAR (mais ça aurait du être 1 en fait).
    Je peux le remplacer par CHAR(1)? Ou je dois mettre en SMALLINT et ajouter un attribut char(1)?

  8. #8
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 909
    Points
    38 909
    Billets dans le blog
    9
    Par défaut
    vous avez bien compris, la requete que je vous ai fournie permet d'identifier les lignes qui causent le rejet de votre contrainte
    A exécuter avant ajout de la contrainte bien sur

    Si vous avez des lignes qui contiennent des valeurs alpha pour la colonne no_cycle, alors :
    - soit c'est une erreur à corriger dans toutes les tables concernées et vous pouvez ensuite remplacer le varchar par du smallint
    - soit c'est le fonctionnement normal ou trop lourd à corriger, alors remplacez le varchar(2) par char(2) ou char(1) si 1 suffit

  9. #9
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    226
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 226
    Points : 119
    Points
    119
    Par défaut
    OK Super!
    J'obtient bien un retour à cette requête.
    Je vais donc rectifier le tir.

    Bonne journée!

    PS : J'avais commencé à remplir les tables. Aprés les avoir vidés. L'ajout de la clé étrangére se fait sans PB.

  10. #10
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 909
    Points
    38 909
    Billets dans le blog
    9
    Par défaut
    L'ajout de clef étrangère sur des tables vides ne vous posera jamais de souci en dehors des problèmes éventuels de syntaxe, puisque le contrôle d'une clef étrangère porte justement sur le contenu

    Pensez à passer à résolu si c'est ok, et à marquer les posts qui ont pu vous aider

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

Discussions similaires

  1. Clé étrangère à partir d'une clé primaire composée
    Par Deciprog dans le forum Langage SQL
    Réponses: 2
    Dernier message: 21/04/2010, 23h11
  2. Réponses: 1
    Dernier message: 16/11/2009, 16h53
  3. Réponses: 1
    Dernier message: 28/04/2009, 02h12
  4. Une appli C++ Builder avec une DLL étrangère
    Par devroot dans le forum C++Builder
    Réponses: 4
    Dernier message: 24/04/2007, 15h17
  5. Comment initialiser une liste de composants avec une boucle ?
    Par EricSid dans le forum Composants VCL
    Réponses: 5
    Dernier message: 06/04/2005, 18h46

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