使用失败的外部检查清理MySQL表

时间:2016-06-22 13:15:35

标签: mysql join foreign-keys mysqldump foreign-key-relationship

我有一个巨大的mysql sql转储文件。但是当我因为外键检查而尝试导入它时,我收到错误。不知何故,数据丢失了,所以我用

导入它
SET SESSION FOREIGN_KEY_CHECKS=0;

它有效,但我正在寻找缺失数据的解决方案。

那么有没有自动方法来查找和删除缺少条目的关系数据以获得干净的数据库转储,或者我必须为每个关系编写manuel SQL,编写查询以删除缺失值?

1 个答案:

答案 0 :(得分:1)

您可以自动执行这样的删除语句:

DELIMITER $$
DROP PROCEDURE IF EXISTS check_foreign $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `check_foreign`()
BEGIN
DECLARE finishing INTEGER DEFAULT 0;
DECLARE vstmt VARCHAR(4000);
DECLARE vtbname VARCHAR(50);
DECLARE vtbnameref VARCHAR(50);
DECLARE vtbcol VARCHAR(50);
DECLARE vtbcolref VARCHAR(50);

DECLARE cr_tables CURSOR FOR select a.table_name, a.referenced_table_name, a.column_name, a.referenced_column_name from information_schema.KEY_COLUMN_USAGE a where a.table_schema = 'protocol_manager' and a.REFERENCED_TABLE_NAME is not null order by a.table_name;
DECLARE CONTINUE HANDLER FOR not found SET finishing = 1;

OPEN cr_tables;

SET vstmt = '';

table_foreign_delete: loop

if finishing = 1 then
    leave table_foreign_delete;
end if;

FETCH cr_tables INTO vtbname, vtbnameref, vtbcol, vtbcolref;

SET vstmt = CONCAT(vstmt, char(10), 'DELETE FROM ', vtbname, ' a WHERE NOT EXISTS (SELECT 1 FROM ', vtbnameref, ' b WHERE a.', vtbcol, ' = b.',  vtbcolref, ');');

end loop table_foreign_delete;

select vstmt;

END$$
DELIMITER ;

您甚至可以进行深度搜索以找到动态执行它的方法。例如,带触发器的临时表。您生成一个删除语句,将其插入临时表,触发激活另一个(func,proc)的插入以执行生成的语句。