mysql - 如何找到 MySQL 表中的无效键?

标签 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 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, CONSTRAINT fk_parent_id FOREIGN KEY (contract_id_amend_source) REFERENCES contracts (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/

相关文章:

android - 即使数据存在于数据库中,也无法从 sqlite 数据库检索数据

mysql - MySQL中任何字段更新时调用HTTP请求的方法

mysql - View 的 SELECT 在 FROM 子句中包含子查询

sql - 在 mysql 中,我如何找到关于所有字段重复的行?

mysql - 错误 1045 : Transferring SQL database from one server to another

SQL:运行总出现次数

mysql - 如何在 MariaDB 中创建表?

php - Codeigniter 排序数据

mysql - 使用通配符作为值本身?

mysql - 表数据的非线性三向求和