MySQL No Puede Agregar Restricción de Clave Foránea


Así que estoy tratando de agregar restricciones de Clave foránea a mi base de datos como un requisito del proyecto y funcionó la primera vez o dos en tablas diferentes, pero tengo dos tablas en las que obtengo un error al intentar agregar las Restricciones de Clave Foránea. El mensaje de error que recibo es:

ERROR 1215 (HY000): No se puede agregar restricción de clave foránea

Este es el SQL que estoy usando para crear las tablas, las dos tablas ofensivas son Patient y Appointment.

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=1;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';

CREATE SCHEMA IF NOT EXISTS `doctorsoffice` DEFAULT CHARACTER SET utf8 ;
USE `doctorsoffice` ;

-- -----------------------------------------------------
-- Table `doctorsoffice`.`doctor`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `doctorsoffice`.`doctor` ;

CREATE  TABLE IF NOT EXISTS `doctorsoffice`.`doctor` (
  `DoctorID` INT(11) NOT NULL AUTO_INCREMENT ,
  `FName` VARCHAR(20) NULL DEFAULT NULL ,
  `LName` VARCHAR(20) NULL DEFAULT NULL ,
  `Gender` VARCHAR(1) NULL DEFAULT NULL ,
  `Specialty` VARCHAR(40) NOT NULL DEFAULT 'General Practitioner' ,
  UNIQUE INDEX `DoctorID` (`DoctorID` ASC) ,
  PRIMARY KEY (`DoctorID`) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;


-- -----------------------------------------------------
-- Table `doctorsoffice`.`medicalhistory`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `doctorsoffice`.`medicalhistory` ;

CREATE  TABLE IF NOT EXISTS `doctorsoffice`.`medicalhistory` (
  `MedicalHistoryID` INT(11) NOT NULL AUTO_INCREMENT ,
  `Allergies` TEXT NULL DEFAULT NULL ,
  `Medications` TEXT NULL DEFAULT NULL ,
  `ExistingConditions` TEXT NULL DEFAULT NULL ,
  `Misc` TEXT NULL DEFAULT NULL ,
  UNIQUE INDEX `MedicalHistoryID` (`MedicalHistoryID` ASC) ,
  PRIMARY KEY (`MedicalHistoryID`) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;


-- -----------------------------------------------------
-- Table `doctorsoffice`.`Patient`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `doctorsoffice`.`Patient` ;

CREATE  TABLE IF NOT EXISTS `doctorsoffice`.`Patient` (
  `PatientID` INT unsigned NOT NULL AUTO_INCREMENT ,
  `FName` VARCHAR(30) NULL ,
  `LName` VARCHAR(45) NULL ,
  `Gender` CHAR NULL ,
  `DOB` DATE NULL ,
  `SSN` DOUBLE NULL ,
  `MedicalHistory` smallint(5) unsigned NOT NULL,
  `PrimaryPhysician` smallint(5) unsigned NOT NULL,
  PRIMARY KEY (`PatientID`) ,
  UNIQUE INDEX `PatientID_UNIQUE` (`PatientID` ASC) ,
  CONSTRAINT `FK_MedicalHistory`
    FOREIGN KEY (`MEdicalHistory` )
    REFERENCES `doctorsoffice`.`medicalhistory` (`MedicalHistoryID` )
    ON DELETE CASCADE
    ON UPDATE CASCADE,
  CONSTRAINT `FK_PrimaryPhysician`
    FOREIGN KEY (`PrimaryPhysician` )
    REFERENCES `doctorsoffice`.`doctor` (`DoctorID` )
    ON DELETE CASCADE
    ON UPDATE CASCADE)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `doctorsoffice`.`Appointment`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `doctorsoffice`.`Appointment` ;

CREATE  TABLE IF NOT EXISTS `doctorsoffice`.`Appointment` (
  `AppointmentID` smallint(5) unsigned NOT NULL AUTO_INCREMENT ,
  `Date` DATE NULL ,
  `Time` TIME NULL ,
  `Patient` smallint(5) unsigned NOT NULL,
  `Doctor` smallint(5) unsigned NOT NULL,
  PRIMARY KEY (`AppointmentID`) ,
  UNIQUE INDEX `AppointmentID_UNIQUE` (`AppointmentID` ASC) ,
  CONSTRAINT `FK_Patient`
    FOREIGN KEY (`Patient` )
    REFERENCES `doctorsoffice`.`Patient` (`PatientID` )
    ON DELETE CASCADE
    ON UPDATE CASCADE,
  CONSTRAINT `FK_Doctor`
    FOREIGN KEY (`Doctor` )
    REFERENCES `doctorsoffice`.`doctor` (`DoctorID` )
    ON DELETE CASCADE
    ON UPDATE CASCADE)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `doctorsoffice`.`InsuranceCompany`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `doctorsoffice`.`InsuranceCompany` ;

CREATE  TABLE IF NOT EXISTS `doctorsoffice`.`InsuranceCompany` (
  `InsuranceID` smallint(5) NOT NULL AUTO_INCREMENT ,
  `Name` VARCHAR(50) NULL ,
  `Phone` DOUBLE NULL ,
  PRIMARY KEY (`InsuranceID`) ,
  UNIQUE INDEX `InsuranceID_UNIQUE` (`InsuranceID` ASC) )
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `doctorsoffice`.`PatientInsurance`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `doctorsoffice`.`PatientInsurance` ;

CREATE  TABLE IF NOT EXISTS `doctorsoffice`.`PatientInsurance` (
  `PolicyHolder` smallint(5) NOT NULL ,
  `InsuranceCompany` smallint(5) NOT NULL ,
  `CoPay` INT NOT NULL DEFAULT 5 ,
  `PolicyNumber` smallint(5) NOT NULL AUTO_INCREMENT ,
  PRIMARY KEY (`PolicyNumber`) ,
  UNIQUE INDEX `PolicyNumber_UNIQUE` (`PolicyNumber` ASC) ,
  CONSTRAINT `FK_PolicyHolder`
    FOREIGN KEY (`PolicyHolder` )
    REFERENCES `doctorsoffice`.`Patient` (`PatientID` )
    ON DELETE CASCADE
    ON UPDATE CASCADE,
  CONSTRAINT `FK_InsuranceCompany`
    FOREIGN KEY (`InsuranceCompany` )
    REFERENCES `doctorsoffice`.`InsuranceCompany` (`InsuranceID` )
    ON DELETE CASCADE
    ON UPDATE CASCADE)
ENGINE = InnoDB;

USE `doctorsoffice` ;


SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
Author: Anthony Neace, 2013-03-21

19 answers

Para encontrar el error específico ejecute esto:

SHOW ENGINE INNODB STATUS;

Y mira en la sección LATEST FOREIGN KEY ERROR.

El tipo de datos de la columna secundaria debe coincidir exactamente con la columna principal. Por ejemplo, dado que medicalhistory.MedicalHistoryID es un INT, Patient.MedicalHistory también necesita ser un INT, no un SMALLINT.

Además, debe ejecutar la consulta set foreign_key_checks=0 antes de ejecutar el DDL para que pueda crear las tablas en un orden arbitrario en lugar de tener que crear todas las tablas principales antes de las tablas secundarias relevantes.

 577
Author: Ike Walker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-21 00:07:03

Había establecido un campo como "Sin signo" y otro no. Una vez que establecí ambas columnas a Sin firmar funcionó.

 106
Author: Satsara Gunaratne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-12 07:06:10
  • El motor debe ser el mismo por ejemplo, InnoDB
  • El tipo de datos debe ser el mismo y tener la misma longitud. por ejemplo, VARCHAR(20)
  • Collation El conjunto de caracteres de las columnas debe ser el mismo. por ejemplo, utf8
    Watchout: Incluso si sus tablas tienen la misma intercalación, las columnas aún podrían tener una diferente.
  • Unique - La clave foránea debe referirse al campo que es único (generalmente clave primaria) en la referencia tabla.
 52
Author: Andrew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-03 15:27:36

Intente usar el mismo tipo de sus claves primarias - int(11) - en las claves foráneas - smallint(5) - también.

Espero que ayude!

 15
Author: Felypp Oliveira,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-20 21:34:45

Confirme que la codificación y el cotejo de caracteres para las dos tablas son los mismos.

En mi propio caso, una de las tablas estaba usando utf8 y la otra estaba usando latin1.

Tuve otro caso donde la codificación era la misma pero la colación diferente. Uno utf8_general_ci el otro utf8_unicode_ci

Puede ejecutar este comando para establecer la codificación y la intercalación de una tabla.

ALTER TABLE tablename CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;

Espero que esto ayude a alguien.

 10
Author: Goke Obasa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-12 11:58:31

Para establecer una CLAVE FORÁNEA en la Tabla B debe establecer una CLAVE en la tabla A.

En el cuadro A: ÍNDICE id (id)

Y luego en la tabla B,

CONSTRAINT `FK_id` FOREIGN KEY (`id`) REFERENCES `table-A` (`id`)
 6
Author: user3707075,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-18 04:34:35

Asegúrese de que ambas tablas estén en formato InnoDB. Incluso si uno está en formato MyISAM, entonces, la restricción de clave foránea no funcionará.

También, otra cosa es que, ambos campos deben ser del mismo tipo. Si uno es INT, entonces el otro también debe ser INT. Si uno es VARCHAR, el otro también debe ser VARCHAR, etc.

 4
Author: Vijay Srinivas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-21 07:05:49

Compruebe las siguientes reglas:

  • Primero comprueba si los nombres se dan correctamente para los nombres de tabla

  • Segundo tipo de datos derecho dar a la clave externa ?

 3
Author: Bhaskar Bhatt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-20 19:05:12

Tenía el mismo problema y la solución era muy simple. Solución: las claves foráneas declaradas en la tabla no deben configurarse como not null.

Referencia : Si especifica una acción SET NULL, asegúrese de que no ha declarado las columnas de la tabla secundaria como NO NULL. (ref )

 3
Author: Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-17 21:00:30

Me enfrenté al problema y pude resolverlo asegurándome de que los tipos de datos coincidieran exactamente .

Estaba usando SequelPro para agregar la restricción y estaba haciendo que la clave primaria no estuviera firmada por defecto .

 2
Author: Learner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-29 05:36:05

Tuve un error similar al crear una clave foránea en una tabla de Muchos a Muchos donde la clave principal consistía en 2 claves foráneas y otra columna normal. Solucioné el problema corrigiendo el nombre de la tabla referenciada, es decir, la empresa, como se muestra en el código corregido a continuación:

create table company_life_cycle__history -- (M-M)
(
company_life_cycle_id tinyint unsigned not null,
Foreign Key (company_life_cycle_id) references company_life_cycle(id) ON DELETE    CASCADE ON UPDATE CASCADE,
company_id MEDIUMINT unsigned not null,
Foreign Key (company_id) references company(id) ON DELETE CASCADE ON UPDATE CASCADE,
activity_on date NOT NULL,
PRIMARY KEY pk_company_life_cycle_history (company_life_cycle_id, company_id,activity_on),
created_on datetime DEFAULT NULL,
updated_on datetime DEFAULT NULL,
created_by varchar(50) DEFAULT NULL,
updated_by varchar(50) DEFAULT NULL
);
 0
Author: iltaf khalid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-15 08:09:20

Tuve un error similar con dos claves foráneas para tablas diferentes pero con los mismos nombres de clave! He cambiado el nombre de las claves y el error se había ido)

 0
Author: Олег Всильдеревьев,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-08 19:35:50

Tuvo un error similar, pero en mi caso me faltaba declarar el pk como auto_increment.

Por si acaso podría ser útil para alguien

 0
Author: Luiz Rolim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-28 12:09:13

Tengo el mismo error. La causa, en mi caso fue:

  1. He creado una copia de seguridad de una base de datos a través de phpmyadmin copiando toda la base de datos.
  2. He creado una nueva base de datos con el mismo nombre que la antigua base de datos y la he seleccionado.
  3. Inicié un script SQL para crear tablas y datos actualizados.
  4. Tengo el error. También cuando deshabilité foreign_key_checks. Aunque la base de datos estaba completamente vacía.

La causa fue: Ya que usé phpmyadmin para crear algunas claves foráneas en la base de datos renombrada: las claves foráneas se crearon con un prefijo de nombre de base de datos, pero el prefijo de nombre de base de datos no se actualizó. Por lo tanto, todavía había referencias en la base de datos de copia de seguridad que apuntaban a la base de datos recién creada.

 0
Author: lsblsb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-22 11:08:17

Mi solución es quizás un poco embarazosa y cuenta la historia de por qué a veces deberías mirar lo que tienes frente a ti en lugar de estos mensajes:)

Había ejecutado un ingeniero avanzado antes, que falló, por lo que eso significaba que mi base de datos ya tenía algunas tablas, luego he estado sentado tratando de corregir los fallos de las contraindicaciones de clave externa tratando de asegurarse de que todo fuera perfecto, pero se topó con las tablas creadas anteriormente, por lo que no prevaleció.

 0
Author: DenLilleMand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-16 16:30:43

Compruebe la firma en ambas columnas de la tabla. Si la columna de la tabla de referencia está FIRMADA, la columna de la tabla referenciada también debe estar FIRMADA.

 0
Author: katwekibs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-23 08:34:24

Una causa adicional de este error es cuando sus tablas o columnas contienen palabras clave reservadas :

A veces uno se olvida de estos.

 0
Author: EssGee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-07 13:11:25

En mi caso, hubo un error de sintaxis que no fue notificado explícitamente por MySQL console al ejecutar la consulta. Sin embargo, SHOW ENGINE INNODB STATUS la sección del comando LATEST FOREIGN KEY ERROR informó,

  Syntax error close to:

  REFERENCES`role`(`id`) ON DELETE CASCADE) ENGINE = InnoDB DEFAULT CHARSET = utf8

Tuve que dejar un espacio en blanco entre REFERENCES y role para que funcionara.

 0
Author: vicke4,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-29 22:04:12

Tuve este mismo problema, luego corrije el nombre del motor como Innodb en ambas tablas padre e hijo y corrije el nombre del campo de referencia REFERENCIAS DE CLAVE FORÁNEA (c_id)x9o_parent_table(c_id)
entonces funciona bien y las mesas están instaladas correctamente. Este será el uso completo para alguien.

 -1
Author: subramanian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-14 10:18:43