MySQL InnoDB - 当数据已经存在违反它时创建CASCADE外键约束?

时间:2010-11-18 15:09:29

标签: mysql foreign-keys innodb

我有一个最初在MyISAM中的数据库,因此没有外键约束。因此,有很多孤立的行,其中外键引用的记录已被删除。

为了解决这个问题,我决定转换为InnoDB并添加外键,使用CASCADE进行更新和删除。但是,当我尝试添加外键时,我得到这样的错误(来自Navicat 8控制台):

1452 - Cannot add or update a child row: a foreign key constraint fails 
(`database`.`#sql-1358_38d`, CONSTRAINT `#sql-1358_38d_ibfk_1` FOREIGN KEY 
(`manufacturerID`) REFERENCES `manufacturer` (`ID`) ON DE)

我知道为什么会这样做 - 因为孤立的行。有没有办法让约束的创建自动清除那些行?完成所有表并找到孤立的行需要很长时间。

这是我正在运行的一个查询,以防它被怀疑:

ALTER TABLE part_number ADD CONSTRAINT
FOREIGN KEY(manufacturerID)
REFERENCES manufacturer(ID)
ON DELETE CASCADE
ON UPDATE CASCADE;

2 个答案:

答案 0 :(得分:2)

编写查找孤立行的查询,然后使用该查询删除。 e.g

SELECT part_number.id FROM part_number LEFT JOIN manufacturer ON (manufacturer.ID = part_number.manufacturerID) where manufacturer.ID IS NULL

答案 1 :(得分:1)

在添加约束之前,您需要删除所有不相关的记录。

你可以采取两种方式。

1使用不存在()

DELETE FROM part_number
 WHERE NOT EXISTS (
           select id from manufacturer
            where part_number.manufacturerID = manufacturer.ID
       )

2。使用临时表(有点难看,但我也会发布)

-- create a temporary table
CREATE TEMPORARY TABLE `temp_ids`
(
  `id` INTEGER
);

-- store all id's that need to be deleted
INSERT INTO `temp_ids`
SELECT part_number.id FROM part_number LEFT JOIN manufacturer ON (manufacturer.ID = part_number.manufacturerID)
WHERE ISNULL(`manufacturer.ID);

-- delete them
DELETE
FROM part_number
WHERE id IN (
  SELECT `id` FROM `temp_ids`
);

-- drop the table
DROP TEMPORARY TABLE `temp_ids`;

请参阅我的相关问题:Handling database integrity

删除所有“死”记录后,您将能够添加约束。

希望这适合你:)