1

我有一个 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;

(我在这里使用的是遗留数据库——我没有想出列名。)

我尝试像这样应用密钥...

ALTER TABLE contracts
ADD CONSTRAINT fk_parent_id
FOREIGN KEY ( contract_id_amend_source )
REFERENCES contracts( id )
ON DELETE CASCADE;

但我得到一个错误...

无法添加或更新子行:外键约束失败 ( contract_tracker/#sql-e18_e9d0a, CONSTRAINT fk_parent_idFOREIGN KEY ( contract_id_amend_source) REFERENCES contracts( id) ON DELETE CASCADE)

好的,有一些无效parent_id的s。

我试着像这样找到他们......

SELECT id, contract_id_amend_source
FROM contracts
WHERE contract_id_amend_source
NOT IN (
  SELECT id
  FROM contracts
);

这将返回大约 20 条记录。我手动修复钥匙。然后再次运行上述查询。现在它不返回任何记录。

我再次尝试ADDFK,但仍然收到“无法添加或更新...”错误。

我想我查找坏键的查询一定是错误的?我该如何解决?

4

1 回答 1

2

看看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 的评论……他是绝对正确的。截断时这通常不是问题(您不关心数据完整性),但在这种情况下您确实关心,所以这个答案的第一部分充其量是一个半解决方案。

于 2013-11-06T00:59:23.513 回答