2016-02-03 4 views
4

У меня есть 2 таблицы MySQL, которые имеют (InnoDB) внешние ключи, переходящие друг в друга. Например,MySQL несколько строк удаления в 2 таблицах, которые МОГУТ ссылаться друг на друга

-- Adminer 4.2.3 MySQL dump 

SET NAMES utf8; 
SET time_zone = '+00:00'; 
SET foreign_key_checks = 0; 
SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO'; 

DROP TABLE IF EXISTS `a`; 
CREATE TABLE `a` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `null_or_b_id` int(11) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `null_or_b_id` (`null_or_b_id`), 
    CONSTRAINT `a_ibfk_1` FOREIGN KEY (`null_or_b_id`) REFERENCES `b` (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

INSERT INTO `a` (`id`, `null_or_b_id`) VALUES 
(1, NULL), 
(2, 2), 
(4, 3), 
(3, 4), 
(5, 5), 
(6, 6), 
(7, 7), 
(8, 8); 

DROP TABLE IF EXISTS `b`; 
CREATE TABLE `b` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `null_or_a_id` int(11) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `null_or_a_id` (`null_or_a_id`), 
    CONSTRAINT `b_ibfk_1` FOREIGN KEY (`null_or_a_id`) REFERENCES `a` (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

INSERT INTO `b` (`id`, `null_or_a_id`) VALUES 
(1, NULL), 
(8, NULL), 
(2, 2), 
(4, 3), 
(3, 4), 
(5, 6), 
(6, 7), 
(7, 8); 

-- 2016-02-03 06:45:07 

То, что я хочу сделать, это удалить записи с идентификаторами 1, 2, 3 и 5 из а и удалить все записи, которые необходимо удалить в А и Б из-за ограничений внешних ключей , Я пробовал:

delete from a where a.id in (1,2,3,5); 

delete a,b from a left join b on b.null_or_a_id = a.id where a.id in (1,2,3,5); 

И выше дает ту же ошибку:

Error in query (1451): Cannot delete or update a parent row: a foreign key constraint fails (`test/multi_delete_with_references`.`b`, CONSTRAINT `b_ibfk_1` FOREIGN KEY (`null_or_a_id`) REFERENCES `a` (`id`)) 

я получаю ту же ошибку, даже если я удалить ограничение внешнего ключа на б, определенное в.

Вещи, которые я не могу сделать:

  • Отключение внешних ключей проверки: потому что обе таблицы также ссылаются на другие таблицы, и я не хочу, чтобы эти таблицы, чтобы осиротевшие строки, если это удаление происходит для того, чтобы вызвать такие осиротевшие строки, мне нужно, чтобы это удаление завершилось неудачей.
  • Сначала удалите из дочерней таблицы: поскольку вы можете видеть в случае строк с идентификатором 2 в обеих таблицах, они ссылаются друг на друга, поэтому нельзя удалять без другого, также в случае строк с идентификаторами 3 и 4 в обеих таблицах, они образуют цепочку самореференций.

Я просмотрел ответ here, и это не сработает для меня, потому что обе таблицы ссылаются друг на друга.

Есть ли выход из этого?

Кстати, я также пытался создавать сложные, вложенные запросы динамически, но это закончилось тем, что бесконечны:

delete from a where id in (1,2,3,5); 
delete from b where null_or_a_id is not null and null_or_a_id in (select * from (select id from a where id in (1,2,3,5)) x); 
delete from a where null_or_b_id is not null and null_or_b_id in (select * from (select id from b where null_or_a_id is not null and null_or_a_id in (select * from (select id from a where id in (1,2,3,5)) x)) x); 
delete from b where null_or_a_id is not null and null_or_a_id in (select * from (select id from a where null_or_b_id is not null and null_or_b_id in (select * from (select id from b where null_or_a_id is not null and null_or_a_id in (select * from (select id from a where id in (1,2,3,5)) x)) x)) x) 
... 

ответ

0

Ваша проблема очень похожа на this one и same solution применяется: сначала удалить ссылки, установив на NULL ссылочные столбцы в тех строках, которые вы собираетесь удалить. Затем удалите.

+0

В итоге я сделал что-то очень похожее на http://stackoverflow.com/a/12652200/1117796. Спасибо за указатель. – SBhojani

Смежные вопросы