如何在MySQL表中找到无效键?
我有一个MySQL表,我想添加一个外键约束 在本例中,它是一个自引用键如何在MySQL表中找到无效键?,mysql,sql,Mysql,Sql,我有一个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 CHEC
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;
(我在这里使用的是一个遗留数据库——我没有想到列名。)
我试着像这样使用钥匙
ALTER TABLE contracts
ADD CONSTRAINT fk_parent_id
FOREIGN KEY ( contract_id_amend_source )
REFERENCES contracts( id )
ON DELETE CASCADE;
SELECT id, contract_id_amend_source
FROM contracts
WHERE contract_id_amend_source
NOT IN (
SELECT id
FROM contracts
);
但我有个错误
无法添加或更新子行:外键约束失败(contract\u tracker/#sql-e18\u e9d0a
,约束fk\u parent\u id
外键(contract\u id\u amend\u source
)引用contracts
(id
)关于删除级联)
好的,有一些无效的parent\u id
s
我试着像这样找到他们
ALTER TABLE contracts
ADD CONSTRAINT fk_parent_id
FOREIGN KEY ( contract_id_amend_source )
REFERENCES contracts( id )
ON DELETE CASCADE;
SELECT id, contract_id_amend_source
FROM contracts
WHERE contract_id_amend_source
NOT IN (
SELECT id
FROM contracts
);
返回大约20条记录。我手动修理钥匙。然后再次运行上面的查询。现在它不返回任何记录
我尝试再次添加FK,但仍然出现“无法添加或更新…”错误
我想我要找到坏钥匙的查询一定是错的吧?我怎样才能修好它?看看
具体而言,如果您只是更改表的数据,则可以使用:
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的评论。。。他完全正确。在截断时,这通常不是问题(您不关心数据完整性),但在这种情况下,您确实关心,因此此答案的第一部分充其量只是半个解决方案。如果他截断表,他将丢失所有数据。没错,我的意思是,他应该在外键检查之间执行他正在执行的任何操作。我更新了答案。您不想这样做,即使它“起作用”,因为它将允许无效数据保留在表中,稍后将返回bite。请包括确切的外键错误,以及contracts.id和contracts.parent_id的完整列定义。该表是INNODB还是MyISAM?它是INNODB表。