web-dev-qa-db-fra.com

Impossible de se passer d'une clé étrangère - MySQL ERROR 1215 (HY000)

J'essaie de créer une base de données pour le système de gestion de la salle de sport, mais je ne comprends pas pourquoi cette erreur me vient J'ai essayé de chercher la réponse ici, mais je ne l'ai pas trouvée.

ERROR 1215 (HY000): Cannot add foreign key constraint

CREATE TABLE sales(
    saleId int(100) NOT NULL AUTO_INCREMENT,
    accountNo int(100) NOT NULL,
    payName VARCHAR(100) NOT NULL,
    nextPayment DATE,
    supplementName VARCHAR(250),
    qty int(11),
    workoutName VARCHAR(100),
    sDate datetime NOT NULL DEFAULT NOW(),
    totalAmount DECIMAL(11,2) NOT NULL,
    CONSTRAINT PRIMARY KEY(saleId, accountNo, payName),
    CONSTRAINT FOREIGN KEY(accountNo) REFERENCES accounts(accountNo) ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT FOREIGN KEY(payName) REFERENCES paymentFor(payName) ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT FOREIGN KEY(supplementName) REFERENCES supplements(supplementName) ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT FOREIGN KEY(workoutName) REFERENCES workouts(workoutName) ON DELETE CASCADE ON UPDATE CASCADE
);
    ALTER TABLE sales AUTO_INCREMENT = 2001;

Voici les tables parentes.

CREATE TABLE accounts(
    accountNo int(100) NOT NULL AUTO_INCREMENT,
    accountType VARCHAR(100) NOT NULL,
    firstName VARCHAR(50) NOT NULL,
    lastName VARCHAR(60) NOT NULL,
    birthdate DATE NOT NULL,
    gender VARCHAR(7),
    city VARCHAR(50) NOT NULL,
    street VARCHAR(50),
    cellPhone VARCHAR(10),
    emergencyPhone VARCHAR(10),
    email VARCHAR(150) NOT NULL,
    description VARCHAR(350),
    occupation VARCHAR(50),
    createdOn datetime NOT NULL DEFAULT NOW(),
    CONSTRAINT PRIMARY KEY(accountNo)
);
    ALTER TABLE accounts AUTO_INCREMENT = 1001; 


CREATE TABLE supplements(
    supplementId int(100) NOT NULL AUTO_INCREMENT,
    supplementName VARCHAR(250) NOT NULL,
    manufacture VARCHAR(100),
    description VARCHAR(150),
    qtyOnHand INT(5),
    unitPrice DECIMAL(11,2),
    manufactureDate DATE,
    expirationDate DATE,
    CONSTRAINT PRIMARY KEY(supplementId, supplementName)
);
    ALTER TABLE supplements AUTO_INCREMENT = 3001;

CREATE TABLE workouts(
    workoutId int(100) NOT NULL AUTO_INCREMENT,
    workoutName VARCHAR(100) NOT NULL,
    description VARCHAR(7500) NOT NULL,
    duration VARCHAR(30),
    CONSTRAINT PRIMARY KEY(workoutId, workoutName)
);
    ALTER TABLE workouts AUTO_INCREMENT = 4001;



CREATE TABLE paymentFor(
    payId int(100) NOT NULL AUTO_INCREMENT,
    payName VARCHAR(100) NOT NULL,
    amount DECIMAL(11,2),
    CONSTRAINT PRIMARY KEY(payId, payName)
);
    ALTER TABLE paymentFor AUTO_INCREMENT = 5001;

Pouvez-vous m'aider avec ce problème? Merci.

10
Dhanuka

Pour qu'un champ soit défini en tant que foreign key, le champ parent référencé doit avoir un index défini.

Selon la documentation sur les contraintes foreign key

REFERENCES parent_tbl_name (index_col_name, ...)

Définissez une INDEX sur workouts.workoutName, paymentFor.paymentName et supplements.supplementName respectivement. Et assurez-vous que les définitions de colonne enfant doivent correspondre à celles de leurs définitions de colonne parent. 

Changez la définition de la table workouts comme ci-dessous: 

CREATE TABLE workouts(
    workoutId int(100) NOT NULL AUTO_INCREMENT,
    workoutName VARCHAR(100) NOT NULL,
    description VARCHAR(7500) NOT NULL,
    duration VARCHAR(30),

    KEY ( workoutName ), -- <---- this is newly added index key

    CONSTRAINT PRIMARY KEY(workoutId, workoutName)
);

Changez la définition de la table supplements comme ci-dessous: 

CREATE TABLE supplements(
    supplementId int(100) NOT NULL AUTO_INCREMENT,
    supplementName VARCHAR(250) NOT NULL,
    manufacture VARCHAR(100),
    description VARCHAR(150),
    qtyOnHand INT(5),
    unitPrice DECIMAL(11,2),
    manufactureDate DATE,
    expirationDate DATE,

    KEY ( supplementName ), -- <---- this is newly added index key

    CONSTRAINT PRIMARY KEY(supplementId, supplementName)
);

Changez la définition de la table paymentFor comme ci-dessous: 

CREATE TABLE paymentFor(
    payId int(100) NOT NULL AUTO_INCREMENT,
    payName VARCHAR(100) NOT NULL,
    amount DECIMAL(11,2),

    KEY ( payName ), -- <---- this is newly added index key

    CONSTRAINT PRIMARY KEY(payId, payName)
);

Maintenant, changez la définition de la table enfant comme suit: 

CREATE TABLE sales(
    saleId int(100) NOT NULL AUTO_INCREMENT,
    accountNo int(100) NOT NULL,
    payName VARCHAR(100) NOT NULL,
    nextPayment DATE,
    supplementName VARCHAR(250) NOT NULL,
    qty int(11),
    workoutName VARCHAR(100) NOT NULL,
    sDate datetime NOT NULL DEFAULT NOW(),
    totalAmount DECIMAL(11,2) NOT NULL,
    CONSTRAINT PRIMARY KEY(saleId, accountNo, payName),
    CONSTRAINT FOREIGN KEY(accountNo) 
       REFERENCES accounts(accountNo) 
       ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT FOREIGN KEY(payName) 
       REFERENCES paymentFor(payName) 
       ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT FOREIGN KEY(supplementName) 
       REFERENCES supplements(supplementName) 
       ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT FOREIGN KEY(workoutName) 
       REFERENCES workouts(workoutName) 
       ON DELETE CASCADE ON UPDATE CASCADE
);

Faire référence à

[CONTRAINT [symbole]] TOUCHE ÉTRANGÈRE
[nom_index] (nom_colonne_index, ...)
REFERENCES tbl_name (index_col_name, ...)
[ON DELETE reference_option]
[ON UPDATE reference_option] 

reference_option:
RESTRICT | CASCADE | SET NULL | PAS D'ACTION 

20
Ravinder Reddy

Si jamais vous voulez savoir pourquoi cette erreur a été commise, il vous suffit d'exécuter la commande ci-dessous et de rechercher " LATEST FOREIGN ERRING ERROR "

Commande à exécuter: -

mysql> SHOW ENGINE INNODB STATUS

Vous saurez la raison de vos erreurs.

29
John Cargo

Clés étrangères sont un moyen de mettre en œuvre des relations/contraintes entre les colonnes de différentes tables.

Il existe différentes catégories de contraintes qui influent sur la manière dont elles sont appliquées lorsqu'une ligne est mise à jour ou supprimée de la table parent:

Cascade: Si une ligne est supprimée du parent, toutes les lignes de la table enfant ayant une valeur FK correspondante seront également supprimées. De même pour les modifications de la valeur dans la table parente.

Restrict: Une ligne ne peut pas être supprimée de la table parent si cela enfreignait une contrainte FK avec la table enfant. De même pour les modifications de la valeur dans la table parente.

No Action: Très semblable à «Restreindre» sauf que tous les événements/déclencheurs de la table parent seront exécutés avant que la contrainte ne soit appliquée - ce qui donnera au rédacteur de l'application l'option de résoudre tout conflit de contrainte FK à l'aide d'une procédure stockée.

Set NULL: Si NULL est une valeur autorisée pour la colonne FK de la table enfant, elle sera définie sur NULL si les données associées de la table parent sont mises à jour ou supprimées.

Set Default: s'il existe une valeur par défaut pour la colonne FK dans la table enfant, elle sera utilisée si les données associées dans la table parent sont mises à jour ou supprimées. Notez que ceci n'est pas implémenté dans cette version - la contrainte peut être ajoutée au schéma, mais toute suppression ou mise à jour ultérieure de la colonne dans la table parent échouera.

4
user4757271

Quelques fois, vous obtiendrez cette erreur "# 1215 - Impossible d'ajouter une contrainte de clé étrangère" en raison de l'incompatibilité de la table TYPE (InnoDB, MyISAM, ..).

Alors changez votre type de table en idem et essayez d’appliquer une contrainte de clé étrangère

mysql> ALTER TABLE table_name ENGINE=InnoDB;

mysql> ALTER TABLE Orders ADD FOREIGN KEY (P_Id) REFERENCES Persons(P_Id)

3
kadhiresan k

Cela pourrait fonctionner pour certaines personnes. Ajoutez simplement le jeu de caractères par défaut comme utf8

DEFAULT CHARACTER SET = utf8;
2
edem

J'avais la même erreur. La raison en était que je faisais référence à une colonne dans une table créée avec charset utf8 à partir d'une table créée en utilisant charset latin.

Les tables créées à l'aide de l'utilitaire de création de tables mySQL Workbench ont un jeu de caractères latin par défaut.

Une approche simple pour savoir si vous utilisez Workbench consiste à afficher l’instruction de création de table de n’importe quelle table. Vous aurez la chaîne de caractères par défaut à la fin.

1

Je ne réponds pas à la question ci-dessus mais juste pour les personnes qui rencontreront la même erreur mysql.

Tout ce que j'ai fait est de changer le moteur de table référencé en innodb.

0
Peter

Je rencontre cette erreur. J'ajoute une contrainte de clé étrangère pour une colonne qui a une «contrainte non nulle», mais j'ai spécifié l'option «on delete delete null» dans la contrainte étrangère. C’est une contradiction qu’il ne sera peut-être pas évident au début.

Voici mes deux tables:

CREATE TABLE study (
    id int(11) NOT NULL AUTO_INCREMENT primary key,
    name varchar(100) NOT NULL,
    introduction text,
    objective varchar(250) DEFAULT NULL,
    method text,
    result text,
    conclusion varchar(250) DEFAULT NULL,
    future_action varchar(100) DEFAULT NULL
);

drop table client_study;
CREATE TABLE client_study (
      id int(11) NOT NULL AUTO_INCREMENT primary key,
      client_id int(11),
      study_id int(11) not null, --If delete 'not null' error goes away!
      contact_person int(11),
      effective_date datetime DEFAULT CURRENT_TIMESTAMP,
      trial_site int(11) DEFAULT NULL,
      UNIQUE KEY unqidx_client_study (client_id,study_id)
);

ALTER TABLE client_study
ADD CONSTRAINT FOREIGN KEY (study_id) REFERENCES study(id)
ON DELETE SET NULL ON UPDATE CASCADE;

ERROR 1215 (HY000): Cannot add foreign key constraint

Si vous supprimez la contrainte NOT NULL sur la colonne study_id de la table client_study, la clé étrangère peut être ajoutée. L'autre alternative consiste à conserver la contrainte non nulle sur la table client_table, mais à modifier la définition de la clé étrangère pour ne supprimer aucune action ou d'autres choix.

0
Kemin Zhou