2016-11-15 6 views
2

Ich bestätige, dass dies hier mehrmals gestellt wurde, und ich habe viele Antworten durchgesehen.MySQL Errno 150 (falscher Fremdschlüssel) für CREATE TABLE

Ich weiß, dass errno150 verweist auf eine Tabelle mit einem falschen Fremdschlüssel, und ich habe eine vorherige Antwort here gesehen. Ich habe dort alle Zustände überprüft und kann das nicht herausfinden. Ich weiß nicht, ob ich etwas Offensichtliches vermisse.

Das die Java implentation von MySQL verwendet, habe ich eine switch-Anweisung, die wie so zwei Tabellen (im Moment) erzeugt:

//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; 
      } 

Adresse erzeugt fein (keine Fremdschlüssel), Patient errno150 gibt . Gleiche Engine, gleicher Zeichensatz, gleicher Datentyp (sogar kopiert, um 100% sicher zu sein), neu erstellte (leere) Tabellen, beide nicht temporär.

Danke.

P.S. Ich kann SHOW ENGINE INNODB STATUS nicht verwenden, da ich keine ausreichend hohe Berechtigungsstufe habe.

Vollfehlermeldung:

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

können Sie den gesamten Fehler einfügen? Was hast du in der mysql-Befehlszeile? – Jordon

+1

@ShivaShinde Es ist über Java erstellt, ich kann den vollständigen Fehler im ursprünglichen Beitrag hinzufügen. –

+1

Bitte fügen Sie den gesamten Fehler hinzu !! – Jordon

Antwort

2

Wenn Sie einen Fremdschlüssel erstellen, die beiden Spalten in der gleichen Zeile der übergeordneten Tabelle übereinstimmt Sie einen einzigen Fremdschlüssel für beiden Spalten angeben müssen (im Gegensatz zu zwei getrennten FK Einschränkungen für jeden Säule).

für mich diese mit MySQL arbeitet 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

Da die Adresstabelle keine Probleme hat, ist dies im Zusammenhang mit den Referenzen des Patiententisches und ich Team gehe davon ist der Name die Datenbank:

  1. Von dem, was ich hier sehe, sollte die referenzierte Spalte indexiert werden. Sie haben einen Index für beide erstellt (houseNo, postCode) zusammen, warum nicht versuchen, den Index für sie separat zu erstellen und sehen, ob das für Sie funktioniert?

  2. Obwohl Sie erwähnt haben, dass Sie die gleiche Engine, den Zeichensatz usw. verwenden, warum erwähnen Sie sie nicht explizit in der obigen Abfrage und führen Sie sie aus. Könnten Sie ENGINE = InnoDB in Ihren Abfragen hinzufügen?

Bitte lassen Sie mich wissen, wenn es nicht für Sie arbeitet.

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

+0

Danke für Ihre Hilfe.Nach dem Versuch, Ihre Vorschläge (von denen nicht funktioniert, leider). Ich habe beschlossen, einen Kompromiss einzugehen, indem ich der Adresstabelle eine automatisch generierte ID als einzelnen Primärschlüssel und Fremdschlüssel für Patient hinzufüge. Ich poste es als Antwort (obwohl ich mir bewusst bin, dass es nicht wirklich ist). Danke noch einmal. –

0

So ist die Antwort (mehr ein Kompromiss) kam ich zu:

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

Erstellen Sie ein zusätzliches Feld in ‚Adresse‘ mit einer ID, die der Primärschlüssel ist und die einzige referenzierten Fremdschlüssel in 'Patient'. Es ist nicht ideal, aber es ist funktional.

Verwandte Themen