Обновление значений с ограничением внешнего ключа

Я немного новичок в SQL, поэтому я не уверен, правильно ли я поступаю. У меня есть две таблицы, которые построены таким образом:

CREATE TABLE `TableA` (
  `id_A` int(11) NOT NULL,
  `name` varchar(100) NOT NULL,
  PRIMARY KEY  (`id_A`),
  UNIQUE KEY `name_UNIQUE` (`name`)
);

CREATE TABLE `TableB` (
  `id_B` int(11) NOT NULL,
  `id_A` int(11) NOT NULL,
  PRIMARY KEY  (`id_B`),
  KEY `id_A` (`id_A`),
  CONSTRAINT `fk_id_A` FOREIGN KEY (`id_A`) REFERENCES `TableA` (`id_A`),
);

Таким образом, эти таблицы связаны по полю id_A и ограничению, показанному в таблице B. Теперь, по некоторым внешним причинам, я должен обновить некоторые значения поля id_A в таблице A и, конечно, я должен обновить связанные строки в таблице B.

Моя первая попытка заключалась в непосредственном использовании запроса UPDATE, но я получил сообщение об ошибке, говорящее, что ограничение не допускает изменения, поскольку id_A использовался TableB (дох!):

Код ошибки: 1451. Не удается удалить или обновить родительскую строку: ограничение внешнего ключа не работает («myserver/TableB», CONSTRAINT «k_id_A» FOREIGN KEY («id_A») REFERENCES «TableA» («id_A»)))

Итак, моей первой мыслью было отключить ограничение, изменить таблицу и снова установить ограничение. Однако это должно быть частью инструмента, предназначенного для редактирования чего-либо в базе данных, и я хотел бы избежать отключения (или удаления) ограничения, поскольку кто-то может закрыть инструмент в середине обновления или что-то еще и покинуть таблицу без этого.

Я пытался использовать транзакцию, содержащую нужные мне запросы, вместо того, чтобы просто выполнять несколько запросов, но я все еще получаю эту предыдущую ошибку. Пока мои идеи таковы:

  1. Отбросьте ограничение, обновите и снова установите ограничение.
  2. Дублируйте все в таблице A, используя новые значения, обновите таблицу B, чтобы использовать новые значения в таблице A, и удалите предыдущие записи в таблице A.
  3. Извлеките все, поместите все в БД, измените локальные данные, а затем поместите все обратно в базу данных.

Есть ли лучший способ сделать это? Я использую MySQL 5.0.27 и для проверки своих запросов (и транзакций) использую MySQL Workbench 6.2.

Спасибо всем.


person Rodrigo    schedule 29.12.2014    source источник


Ответы (1)


Прежде всего, редактирование ключа ID строки — вообще плохая идея, но я не буду подвергать сомнению это.

Вы должны использовать поведение CASCADE в своем ограничении, изменяя текущую таблицу.

[...] CONSTRAINT `fk_id_A` FOREIGN KEY (`id_A`) REFERENCES `TableA` (`id_A`) ON UPDATE CASCADE

[edit] Подробнее об этой теме в этом вопросе.

person Jean    schedule 29.12.2014