352

そのため、プロジェクトの要件として外部キー制約をデータベースに追加しようとしていますが、最初または 2 回は別のテーブルで機能しましたが、外部キー制約を追加しようとするとエラーが発生するテーブルが 2 つあります。私が得るエラーメッセージは次のとおりです。

エラー 1215 (HY000): 外部キー制約を追加できません

これは、テーブルを作成するために使用している SQL です。問題のある 2 つのテーブルはPatientAppointmentです。

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;
4

25 に答える 25

870

特定のエラーを見つけるには、次のコマンドを実行します。

SHOW ENGINE INNODB STATUS;

そして、セクションを見てくださいLATEST FOREIGN KEY ERROR

子列のデータ型は、親列と正確に一致する必要があります。たとえば、medicalhistory.MedicalHistoryIDはであるためINTPatient.MedicalHistoryもである必要があります。INTではありませんSMALLINT

また、DDLを実行する前にクエリset foreign_key_checks=0を実行して、関連する子テーブルの前にすべての親テーブルを作成する必要がなく、任意の順序でテーブルを作成できるようにする必要があります。

于 2013-03-20T21:30:21.237 に答える
107
  • エンジンは同じである必要があります (例: InnoDB)
  • データ型は同じで、同じ長さでなければなりません。例: VARCHAR(20)
  • 照合列の文字セットは同じである必要があります。例: utf8
    注意: テーブルの照合順序が同じであっても、列の照合順序が異なる場合があります。
  • 一意- 外部キーは、参照テーブルで一意のフィールド(通常は主キー)を参照する必要があります。
于 2016-01-22T17:59:56.743 に答える
23

同じタイプの主キー - int(11) - を外部キー - smallint(5) - にも使用するようにしてください。

それが役に立てば幸い!

于 2013-03-20T21:34:45.480 に答える
16

2 つのテーブルの文字エンコードと照合順序が同じであることを確認します。

私の場合、テーブルの 1 つは を使用utf8し、もう 1 つは を使用していlatin1ました。

エンコーディングは同じですが、照合順序が異なる別のケースがありました。もうutf8_general_ci一方utf8_unicode_ci

このコマンドを実行して、テーブルのエンコードと照合を設定できます。

ALTER TABLE tablename CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;

これが誰かに役立つことを願っています。

于 2016-06-29T12:07:56.307 に答える
8

私は同じ問題を抱えていましたが、解決策は非常に簡単でした。解決策 : テーブルで宣言された外部キーは、非 null に設定しないでください。

参照 : SET NULL アクションを指定する場合は、子テーブルの列を NOT NULL として宣言していないことを確認してください。(参照 )

于 2015-03-04T23:53:47.420 に答える
3

私はこの問題に直面し、データ型が正確に一致していることを確認することで解決できました。

制約を追加するために SequelPro を使用していましたが、デフォルトで主キーを unsigned にしていました。

于 2016-02-29T05:36:05.730 に答える
3

両方のテーブル列の署名を確認してください。参照するテーブルの列が SIGNED の場合、参照されるテーブルの列も SIGNED にする必要があります。

于 2016-11-23T08:34:24.710 に答える
0

同様のエラーがありましたが、私の場合、pk を auto_increment として宣言することができませんでした。

万が一、誰かの参考になれば

于 2015-02-28T12:09:13.613 に答える
0

私の解決策は少し恥ずかしいかもしれませんが、これらの投稿ではなく、目の前にあるものを見る必要がある理由を物語っています:)

以前にフォワード エンジニアを実行したことがありますが、失敗したため、データベースには既にいくつかのテーブルがあり、すべてが完璧であることを確認するために外部キー制約の失敗を修正しようとして座っていましたが、以前に作成されたテーブルであるため、一般的ではありませんでした。

于 2016-08-16T16:30:43.507 に答える
0

同じエラーが発生しました。私の場合の原因は次のとおりです。

  1. データベース全体をコピーして、phpmyadmin を介してデータベースのバックアップを作成しました。
  2. 古いデータベースが選択していなかったのと同じ名前で新しいデータベースを作成しました。
  3. 更新されたテーブルとデータを作成する SQL スクリプトを開始しました。
  4. エラーが発生しました。また、foreign_key_checks を無効にしたとき。データベースは完全に空でしたが。

原因: phpmyadmin を使用して、名前を変更したデータベースにいくつかの外部キーを作成したため、外部キーはデータベース名のプレフィックスで作成されましたが、データベース名のプレフィックスは更新されませんでした。そのため、新しく作成されたデータベースを指すバックアップデータベースにはまだ参照がありました。

于 2015-12-22T11:08:17.833 に答える
-1

この同じ問題があり、親テーブルと子テーブルの両方でエンジン名を Innodb として修正し、参照フィールド名 FOREIGN KEY ( c_id) REFERENCES x9o_parent_table( c_id)を修正する
と、正常に動作し、テーブルが正しくインストールされます。これは誰かのために完全に使用されます。

于 2015-10-14T10:18:43.700 に答える