我有一个 MySQL 表,我想添加一个外键约束。
在这种情况下,它是一个自引用键...
CREATE TABLE `contracts` (
`id` int(11) NOT NULL auto_increment,
`contract_id_amend_source` int(11) default NULL,
# ...
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14834 DEFAULT CHARSET=latin1 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC;
(我在这里使用遗留数据库——我没有想出列名。)
我尝试像这样应用 key ...
ALTER TABLE contracts
ADD CONSTRAINT fk_parent_id
FOREIGN KEY ( contract_id_amend_source )
REFERENCES contracts( id )
ON DELETE CASCADE;
但是我得到一个错误...
Cannot add or update a child row: a foreign key constraint fails (
contract_tracker/#sql-e18_e9d0a
, CONSTRAINTfk_parent_id
FOREIGN KEY (contract_id_amend_source
) REFERENCEScontracts
(id
) ON DELETE CASCADE)
好的,有一些无效的parent_id
。
我试着像这样找到它们......
SELECT id, contract_id_amend_source
FROM contracts
WHERE contract_id_amend_source
NOT IN (
SELECT id
FROM contracts
);
返回大约 20 条记录。我手动修复 key 。然后再次运行上面的查询。现在它不返回任何记录。
我尝试再次ADD
FK,但我仍然收到“无法添加或更新...”错误。
我想我查找坏键的查询一定是错误的?我该如何解决?
最佳答案
看看truncate foreign key constrained table .
具体来说,如果您只是更改表的数据,您可以使用:
SET FOREIGN_KEY_CHECKS=0;
... do whatever you need here that is giving you problems...
SET FOREIGN_KEY_CHECKS=1;
我收藏了这个,非常有用。
您也可以尝试通过以下方式找到额外的隐藏记录:
SELECT id
FROM contracts
LEFT JOIN contracts
ON contracts.id=contracts.parent_id
WHERE contracts.id IS NOT NULL
AND
contracts.parent_id IS NULL;
简单说一下@Michael - sqlbot 的评论......他是绝对正确的。这在截断时通常不是问题(您不关心数据完整性),但在这种情况下您确实关心,所以这个答案的第一部分充其量只是一半的解决方案。
关于mysql - 如何找到 MySQL 表中的无效键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19802087/