2011-04-22 68 views
13

我使用MySQL的工作台在表中添加一个外键,但有些奇怪的错误发生了,这是SQL语句:不能在mysql中添加外键?

ALTER TABLE `tansung`.`Declaration` ADD COLUMN `goodsId` INT(11) NOT NULL AFTER `declarationId` , 
    ADD CONSTRAINT `goodsId` 
     FOREIGN KEY (`goodsId`) 
     REFERENCES `tansung`.`Goods` (`goodsId`) 
     ON DELETE NO ACTION 
     ON UPDATE NO ACTION 
    , ADD INDEX `goodsId` (`goodsId` ASC) ; 

当我点击应用,惊喜出来!

ERROR 1005: Can't create table 'tansung.#sql-1b10_1' (errno: 150) 

SQL Statement: 

ALTER TABLE `tansung`.`Declaration` ADD COLUMN `goodsId` INT(11) NOT NULL AFTER `declarationId` , 
    ADD CONSTRAINT `goodsId` 
     FOREIGN KEY (`goodsId`) 
     REFERENCES `tansung`.`Goods` (`goodsId`) 
     ON DELETE NO ACTION 
     ON UPDATE NO ACTION 
    , ADD INDEX `goodsId` (`goodsId` ASC) 


ERROR: Error when running failback script. Details follow. 


ERROR 1050: Table 'Declaration' already exists 

SQL Statement: 

CREATE TABLE `Declaration` (
    `declarationId` int(11) NOT NULL, 
    PRIMARY KEY (`declarationId`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

我无法找出逻辑上的任何错误,甚至不明白错误,请给我一个帮助。

+1

该错误似乎不言自明;您正尝试创建一个名为'Declaration'的表,该表已存在... – 2011-04-22 17:27:23

+0

确保您没有在窗口中运行所有SQL代码。看起来您正在运行ALTER TABLE代码,然后立即执行CREATE TABLE代码...确保您只运行ALTER TABLE代码以防止出现此错误。 – acconrad 2011-04-22 17:30:35

+0

@Brian Driscoll真正的错误出现在代码块的顶部'ERROR 1005:Can not create table'tansung。#sql-1b10_1'(errno:150)' – 2011-04-22 17:58:06

回答

0

Goods.goodsIdDeclarations.goodsId的类型定义必须相同,否则您将获得errno: 150

确保它们都是相同的数据类型,在Declarations表中看起来为goodsId INT(11) NOT NULLGoodsCREATE TABLE声明是什么?

+0

它可能有一些关系,我设置“lower_case_table_names = 0” – firefly 2011-04-23 04:47:37

+0

,因为我需要ORM genenrate实体类,所以我想使用upper_case,但mysql在Windows只采取lower_case表名,所以我设置lower_case_table_names = 0,但是当我添加外键时可能会有一些问题。 – firefly 2011-04-23 04:51:03

5

我得到这个错误,当表被链接(在你的情况下,商品)使用MyISAM存储,并且你添加索引的表(在你的情况下,声明)使用InnoDB的。

您可以通过数据库目录中的文件来说明这一点。 MyISAM表将不得不像文件:

table_name.frm 
table_name.MYD 
table_name.MYI 

的InnoDB表将只具有:

table_name.frm 

MyISAM不支持外键约束。我建议你的商品表转换为InnoDB的(虽然,首先看看文档,做一些basic research):

ALTER TABLE Goods ENGINE=INNODB; 

进行此更改后,我的ADD INDEX操作成功完成。

+1

这是问题,谢谢! – DerShodan 2012-02-01 10:46:19

+0

解决了我的问题 - 谢谢! – 2014-07-23 12:14:34

16

整个数据库中的所有外键名都必须是唯一的。如果您已经有一个名为'goodsId'的外键,即使在另一个表上,您也会收到此错误。

如果相关列不具有完全相同的类型(如INT)和约束(UNIQUE和这样),您会收到错误。

+0

此解决方案适用于我。 非常感谢 – 2017-02-01 18:34:16

0

我有同样的问题。它似乎有在子表中的一些数据,这是不存在的父表。你可以做一个外部联接看到差异,你可以指定一个有效的身份证不匹配的行或删除:

DELETE FROM books 
WHERE NOT EXISTS (
    SELECT * FROM users 
    WHERE books.user_id = users.id 
) 
0

当我得到的错误是监守我尝试更新表已经有数据int并且数据不符合FK restrictions

0

errno 150有很多原因。如果你有SUPER权限,你应该尝试使用

SHOW ENGINE INNODB STATUS

,并会告诉你的原因是什么。如果您没有SUPER权限,则需要查看所有可能的原因。你可以找到如何使用SHOW INNODB STATUS和这里的所有原因的列表:

MySQL Foreign Key Errors and Errno 150

1

像其他人说,首先要确保类型的两列是相同的数据库支持它。之后,确保将密钥保存到其他表的列是有效的。 我遇到了一个问题,我将约束条件添加到现有的列中,并且该数据与其他表中的任何主键都不匹配,因此尝试创建关系会失败。修复它涉及更新所有的列,以确保我的列数据与我试图创建的约束匹配。

10

这可能会发生,原因很多。以下是一些常见原因。你也可以说句法错误,因为这些类型的错误被抛出。

  1. 如果FK(外键)表引擎使用MyISAM和PK(主键)表引擎使用InnoDB。 MyISAM不支持外键约束。所以,你可能想把你的链接表转换成InnoDB。

  2. 整个数据库中的所有外键名称必须是唯一的。如果已经有一个具有相同名称的外键约束,即使在另一个表上,也会收到此错误。

  3. 如果相关列没有完全相同的数据类型(例如INT)和约束(UNIQUE等),则会收到该错误。

+0

谢谢我不知道在整个数据库中的所有外键名称必须是唯一的 – vinay 2014-10-25 09:55:45

+0

不客气@Vinay。很高兴,答案帮助你。 – abhijitcaps 2014-10-31 09:23:38

+0

不匹配的表引擎是我的罪魁祸首。谢谢。 – 2014-11-11 03:09:03

0

第四个可能的问题(对于abhijitcaps提出的三个问题)是您没有将您引用的列作为主键。

1

我发现当试图在phpMyAdmin中执行此操作时,名称中带有连字符的表只会允许一个FK,然后出错。我不知道为什么,但它是很容易解决,我只是重拍

CREATE TABLE `something_new` LIKE `something-old`; 
DROP TABLE `something-old`; 

情况因人而异。