繁体   English   中英

用于创建表的MySQL Errno 150(不正确的外键)

[英]MySQL Errno 150 (incorrect foreign key) for CREATE TABLE

我承认在这里已经被问过几次了,并且已经浏览了很多答案。

我知道errno150引用的表具有错误的外键,并且我在这里看到了先前的答案。 我检查了那里的每一种情况,无法解决。 不知道我是否缺少明显的东西。

这是使用MySQL的Java实现,我有一个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%的可靠性),新创建的(空)表,它们都是非临时的。

谢谢。

PS我无法使用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)

如果要创建与父表的同一行中的匹配的外键约束,则需要为两列指定单个FOREIGN KEY(而不是为每列指定两个单独的FK约束)。

这对我适用于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. 根据我在这里看到的内容,应该对引用的列进行索引。 您已经创建了两个索引( houseNopostCode )在一起,为什么不尝试分别为它们创建索引,看看是否对您postCode

  2. 尽管您提到使用的是相同的引擎,字符集等,但为什么不在上述查询中明确提及它们并运行它们。 您可以在查询中添加ENGINE = InnoDB吗?

如果不适合您,请告诉我。

无法创建表(errno:150)InnoDB添加外键约束

所以答案(更多的妥协)我来到:

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是“患者”中的主键和唯一引用的外键。 它不是理想的,但是可以起作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM