2016-11-15 17 views
2

これは何度かここで尋ねられましたが、私は非常に多くの回答を見てきました。CREATE TABLEのMySQL Errno 150(間違った外部キー)

私は、errno150が誤った外部キーを持つテーブルを参照していることを知っています。以前の回答hereを見ました。私はそこにあるすべての条件をチェックし、これを理解することはできません。私が何かを明らかにしていないかどうかわからない。

これは、MySQLのJavaのimplentationを使用している、私は(現時点では)2つのテーブルを作成し、switchステートメントをしましたので、同じよう:

//Creates the table with the name given to the function and adds all fields & keys 
      switch(tableName){ 
      case "Address": 
       stmt.executeUpdate("CREATE TABLE Address(houseNo INT(4) NOT NULL, " 
         + "firstLine VARCHAR(30) NOT NULL, " 
         + "secondLine VARCHAR(30), " 
         + "city VARCHAR(25) NOT NULL, " 
         + "county VARCHAR(25) NOT NULL, " 
         + "postCode VARCHAR(7) NOT NULL, " 
         + "PRIMARY KEY (houseNo, postCode))"); 
       break; 
      case "Patient": 
       stmt.executeUpdate("CREATE TABLE Patient(patientID INT(8) NOT NULL PRIMARY KEY AUTO_INCREMENT, " 
         + "title VARCHAR (10) NOT NULL, " 
         + "forename VARCHAR(15) NOT NULL, " 
         + "surname VARCHAR(25) NOT NULL, " 
         + "dob DATE NOT NULL, " 
         + "phoneNo CHAR(11) NOT NULL, " 
         + "houseNo INT(4) NOT NULL, " 
         + "postCode VARCHAR(7) NOT NULL, " 
         + "amountOwed DECIMAL(5,2) NOT NULL, " 
         + "FOREIGN KEY (houseNo) REFERENCES Address (houseNo), " 
         + "FOREIGN KEY (postCode) REFERENCES Address (postCode))"); 
       break; 
      } 

アドレスは、(外部キー)の罰金を作成し、患者がerrno150を与えます。同じエンジン、同じ文字セット、同じデータ型(100%確実に貼り付けられたコピーさえも)、新しく作成された(空の)テーブル、どちらも一時的ではありません。

ありがとうございました。

P.S.私は十分な許可レベルを持っていないので、SHOW ENGINE INNODB STATUSを使用することはできません。

完全なエラーメッセージ:

java.sql.SQLException: Can't create table 'team.Patient' (errno: 150) 
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:964) 
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3970) 
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3906) 
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2524) 
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2677) 
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2545) 
    at com.mysql.jdbc.StatementImpl.executeUpdateInternal(StatementImpl.java:1540) 
    at com.mysql.jdbc.StatementImpl.executeLargeUpdate(StatementImpl.java:2595) 
    at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1468) 
    at uk.team.App.makeTable(App.java:146) 
    at uk.team.App.setupEnviro(App.java:80) 
    at uk.team.App.access$1(App.java:45) 
    at uk.team.App$1.run(App.java:33) 
    at java.awt.event.InvocationEvent.dispatch(Unknown Source) 
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source) 
    at java.awt.EventQueue.access$500(Unknown Source) 
    at java.awt.EventQueue$3.run(Unknown Source) 
    at java.awt.EventQueue$3.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source) 
    at java.awt.EventQueue.dispatchEvent(Unknown Source) 
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
    at java.awt.EventDispatchThread.run(Unknown Source) 
+1

あなたは全体のエラーを貼り付けることはできますか?あなたはmysqlコマンドラインで何を得ましたか? – Jordon

+1

@ShivaShindeこれはJavaを使用して作成されたもので、元の投稿に完全なエラーを追加できます。 –

+1

エラー全体を追加してください! – Jordon

答えて

2

あなたはそれぞれのための2つの別々のFK制約とは対照的に、(両方の列のための単一のFOREIGN KEYを指定する必要があり、親テーブルの同じ行に両方列に一致する外部キー制約を作成する場合カラム)。

これは、MySQL 5.6.13で私の作品:

stmt.executeUpdate("CREATE TABLE Address(houseNo INT(4) NOT NULL, " 
     + "firstLine VARCHAR(30) NOT NULL, " 
     + "secondLine VARCHAR(30), " 
     + "city VARCHAR(25) NOT NULL, " 
     + "county VARCHAR(25) NOT NULL, " 
     + "postCode VARCHAR(7) NOT NULL, " 
     + "PRIMARY KEY (houseNo, postCode))"); 
stmt.executeUpdate("CREATE TABLE Patient(patientID INT(8) NOT NULL PRIMARY KEY AUTO_INCREMENT, " 
     + "title VARCHAR (10) NOT NULL, " 
     + "forename VARCHAR(15) NOT NULL, " 
     + "surname VARCHAR(25) NOT NULL, " 
     + "dob DATE NOT NULL, " 
     + "phoneNo CHAR(11) NOT NULL, " 
     + "houseNo INT(4) NOT NULL, " 
     + "postCode VARCHAR(7) NOT NULL, " 
     + "amountOwed DECIMAL(5,2) NOT NULL, " 
     + "FOREIGN KEY (houseNo, postCode) REFERENCES Address (houseNo, postCode))"); 
1

アドレステーブルには何の問題を持っていないので、これは患者テーブルの参照に、より関連していると私はチームを想定していますが、データベースの名前です:

  1. ここからわかるように、参照されている列にはインデックスを付ける必要があります。両方のインデックス(houseNopostCode)を一緒に作成しました。別々にインデックスを作成して、それがうまくいくかどうか確認してみてください。

  2. あなたは同じエンジン、文字セットなどを使用していると述べていますが、上記のクエリで明示的に言及して実行しないのはなぜですか? ENGINE = InnoDBをクエリに追加できますか?

あなたにはうまくいかない場合は教えてください。

Can't create table (errno: 150) InnoDB adding foreign key constraints

+0

ご協力ありがとうございます。あなたの提案を試した後(残念ながらどちらもうまくいきませんでした)。私は、患者のための単一の主キーと外部キーとしてアドレステーブルに自動生成されたIDを追加することによって妥協することに決めました。私は答えとして掲示します(私はそれが本当ではないことはよく知っていますが)。再度、感謝します。 –

0

だから私はに来た答え(もっと妥協):

switch(tableName){ 
      case "Address": 
       stmt.executeUpdate("CREATE TABLE Address(houseID INT(8) NOT NULL PRIMARY KEY AUTO_INCREMENT, " 
         + "houseNo INT(4) NOT NULL, " 
         + "firstLine VARCHAR(30) NOT NULL, " 
         + "secondLine VARCHAR(30), " 
         + "city VARCHAR(25) NOT NULL, " 
         + "county VARCHAR(25) NOT NULL, " 
         + "postCode VARCHAR(7) NOT NULL)"); 
       break; 
      case "Patient": 
       stmt.executeUpdate("CREATE TABLE Patient(patientID INT(8) NOT NULL PRIMARY KEY AUTO_INCREMENT, " 
         + "title VARCHAR (10) NOT NULL, " 
         + "forename VARCHAR(15) NOT NULL, " 
         + "surname VARCHAR(25) NOT NULL, " 
         + "dob DATE NOT NULL, " 
         + "phoneNo CHAR(11) NOT NULL, " 
         + "houseID INT(8) NOT NULL, " 
         + "amountOwed DECIMAL(5,2) NOT NULL, " 
         + "FOREIGN KEY (houseID) REFERENCES Address (houseID))"); 
       break; 
} 

は、主キーのみ参照する外部キーであるIDと「アドレス」に追加フィールドを作成します。 「患者」の中で。それは理想的ではありませんが、機能的です。

関連する問題