Удаление строк из нескольких таблиц в MySQL

Вот что я пытаюсь сделать:

Удалите проект из таблицы projects и всех изображений, связанных с этим проектом, в таблице images .

Скажем, $del_id = 10

 DELETE FROM projects, images WHERE projects.p_id = '$del_id' AND images.p_id = '$del_id' 

Что не так с этим запросом?

 DELETE projects, images FROM projects, images WHERE projects.p_id = '$del_id' AND projects.p_id = images.p_id; 

Как отметил Chacha102 , проблема вашего запроса заключалась в определении AND в WHERE .

Однако вы можете использовать синтаксис JOIN для multi-table DELETE s, который мне легче читать:

 DELETE projects, images FROM projects LEFT JOIN images ON images.p_id = projects.p_id WHERE projects.p_id = 10; 
 $sql = "DELETE FROM projects, images WHERE projects.p_id = '".$del_id."' or images.p_id = '".$del_id."'"; 

При удалении элемент никогда не встретит оба этих требования, поэтому он должен быть OR не AND

Ответ

 <?php $query = sprintf(" DELETE FROM p, i USING projects p, images i WHERE p.p_id = %d AND p.p_id = i.p_id ", $del_id); ?> 

Тест

проектов

 create table projects ( p_id int unsigned not null auto_increment primary key ); insert into projects (p_id) values (1),(2),(3); select * from projects; -- +------+ -- | p_id | -- +------+ -- | 1 | -- | 2 | -- | 3 | -- +------+ 

изображений

 create table images ( i_id int unsigned not null auto_increment primary key, p_id int unsigned default null ); insert into images (p_id) values (1),(1),(1),(2),(2),(3),(3); select * from images; -- +------+------+ -- | i_id | p_id | -- +------+------+ -- | 1 | 1 | -- | 2 | 1 | -- | 3 | 1 | -- | 4 | 2 | -- | 5 | 2 | -- | 6 | 3 | -- | 7 | 3 | -- +------+------+ 

удалить

 delete from p, i using projects p, images i where p.p_id = i.p_id and p.p_id = 1; 

результат

 select * from projects; -- +------+ -- | p_id | -- +------+ -- | 2 | -- | 3 | -- +------+ select * from images; -- +------+------+ -- | i_id | p_id | -- +------+------+ -- | 4 | 2 | -- | 5 | 2 | -- | 6 | 3 | -- | 7 | 3 | -- +------+------+ 

работает угощение!

Для этого вы должны использовать два отдельных запроса:

 delete from images where p_id = 123; delete from projects where p_id = 123; 

т.е.:

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

И в качестве меры предосторожности вы должны обернуть все это в транзакцию, чтобы получить все или ничего, – хорошо, если вы используете механизм хранения, который поддерживает транзакции, такие как InnoDb.

См. 12.3.1. START TRANSACTION, COMMIT и ROLLBACK Синтаксис , об этом, в руководстве MySQL.

Измените AND в OR.

Возможно, вы захотите использовать ограничение внешнего ключа с каскадным удалением, намного проще, но вам нужно использовать innoDB и создать это ограничение FK. Удалите проект и все связанные с ним изображения также будут удалены.

(Неверный ответ, MySQL позволяет это )

Вы не можете удалить из двух таблиц в одном запросе.

Самое близкое, что вы можете получить, – это перенос двух удалений в транзакцию:

 begin transaction delete from projects where p_id = $del_id delete from images where p_id = $del_id commit transaction