Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在MySQL表中找到无效键?_Mysql_Sql - Fatal编程技术网

如何在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

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