[MySQL]: УДАЛИТЬ строки из двух зависимых таблиц - PullRequest
5 голосов
/ 06 января 2010

Я пытаюсь удалить все строки в двух зависимых таблицах на основе идентификатора третьей таблицы.

Структура таблицы:

Transaction
-Transaction_ID (primary)
-Timestamp

Purchase
-Item_ID
-Transaction_ID
-Purchase_ID (primary)

Item
-Item_ID (primary)
-Client_ID

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

DELETE dbName.t FROM
  dbName.Transaction t
JOIN
  dbName.Purchase p
 ON
  p.Transaction_ID = t.Transaction_ID
JOIN
  dbName.Item i
 ON
  p.Item_ID = i.Item_ID
WHERE
  Client_ID = 1

Нету ...

Я получаю эту ошибку foreign key constraint fails... - я уверен, что многие из вас не удивлены.

Является ли проблема, что Покупка использует t.Transaction_ID? - (таким образом, этот внешний ключ не будет работать)

ИЛИ, вероятно, есть другие зависимые от t.Transaction_ID данные в этой таблице (я их не нашел).

РЕДАКТИРОВАТЬ: COMPLETE ERROR

Cannot delete or update a parent row: a foreign key constraint fails
(`ItemTracker_dbo/Purchase`, CONSTRAINT `FK_Purchase_Transaction`  
FOREIGN KEY (`Transaction_ID`) REFERENCES `Transaction` (`Transaction_ID`) 
ON DELETE NO ACTION ON UPDATE CASCADE)

Ответы [ 2 ]

4 голосов
/ 06 января 2010

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

Transaction <- Purchase -> Item

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

В качестве альтернативы этому двухэтапному подходу я бы порекомендовал установить ограничение ON DELETE CASCADE и перейти к следующему:

DELETE 
  Transaction 
WHERE 
  Transaction_ID IN (
    SELECT 
      Transaction_ID 
    FROM
      Purchase INNER JOIN Item ON Item.Item_ID = Purchase.Item_ID
    WHERE
      Item.Client_ID = <your Client ID here>
  )

Помните, что это удаляет любые Transaction (и, через CASCADE, любые Purchase), где есть зависимый Item с соответствующим Client_ID, независимо от того, есть ли какие-либо другие предметы в нем. Если это не то, что вы хотите, вопрос должен быть уточнен.

2 голосов
/ 06 января 2010
Transaction <- Purchase -> Item

Ваша проблема в том, что вы пытаетесь удалить Транзакцию перед удалением покупки, правильный способ сделать это - удалить покупку и только затем транзакцию, которую вы можете использовать ON DELETE CASCADE на ваших внешних ключах кажется, что вы используете ON DELETE RESTRICT .

Смотрите здесь: http://dev.mysql.com/doc/refman/5.0/es/innodb-foreign-key-constraints.html

Кроме того, если вы не хотите быть уверенным, что именно по этой причине вы должны дать полную ошибку, СУБД обычно сообщает вам, какое нарушение внешнего ключа вызывает ошибку.

ОБНОВЛЕНИЕ: ваша ошибка прояснила ситуацию, проблема в том, что вы сначала удаляете Покупку, а затем Транзакцию, вам нужно сделать это в обратном направлении или установить ON УДАЛИТЬ КАСКАД в ограничение вашего внешнего ключа

...