tags:

views:

123

answers:

7

Here is what i'm trying to do:

Delete a project from the projects table and all the images associated with that project in the images table.

Lets say $del_id = 10

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

What is wrong with this query?

+3  A: 
$sql = "DELETE FROM projects, images WHERE projects.p_id = '".$del_id."' or images.p_id = '".$del_id."'";

When being deleted, an item will never meet both of these requirements, therefore it must be OR not AND

Chacha102
+1, Replace `AND` with `OR`, good catch
Justin Ethier
+1 for catching the problem... I suggest using the `JOIN` syntax for a multi-table `DELETE`, which would have avoided such an ambiguity.
Daniel Vassallo
here i got this to work (i had to list tables after DELETE)DELETE projects, images FROM projects, images WHERE projects.pr_id = '$del_id' AND images.pr_id = '$del_id'
Ross
That last comment will delete everything from those tables
barfoon
A: 

(Wrong answer, MySQL allows this)

You can't delete from two tables in one query.

The closest you can get is wrap the two deletes in a transaction:

begin transaction
delete from projects where p_id = $del_id
delete from images where p_id = $del_id
commit transaction
Andomar
This is only allowed if the table is INNODB.
Brant
@Andomar, you certainly **can** delete from more than one table in a single query. My answer provides an example specifically for you.
macek
@Smotchkiss: the first line of my answer says the answer is wrong, so I had figured that one out :)
Andomar
@Andomar, my mistake. I thought that was in reply to someone else's answer.
macek
A: 

You should use two separate queries to do that :

delete from images where p_id = 123;

delete from projects where p_id = 123;

i.e. :

  • First, delete the images, that depend on the project (foreign key ? )
  • And, when nothing depends on the project anymore, delete the project itself.


And, as a security precaution, you should wrap all this in a transaction, to get a all or nothing behavior -- well, if you are using a storage engine that suppors transactions, like InnoDb.

See 12.3.1. START TRANSACTION, COMMIT, and ROLLBACK Syntax, about that, in the MySQL Manual.

Pascal MARTIN
+1  A: 
DELETE projects, images 
FROM projects, images 
WHERE projects.p_id = '$del_id' 
AND projects.p_id = images.p_id;
Brant
@Ross - Glad this worked out for you.
Brant
A: 

Change the AND into an OR.

You might want to use a foreign key constraint with a cascading delete, much easier, but you have to use innoDB and create this FK-constraint. Delete the project and all related images will be deleted as well.

Frank Heikens
+1  A: 

As Chacha102 noted, the problem of your query was the AND in the WHERE clause.

However, you may want to use the JOIN syntax for multi-table DELETEs, which I find easier to read:

DELETE     projects, images
FROM       projects 
LEFT JOIN  images ON images.p_id = projects.p_id
WHERE      projects.p_id = 10;
Daniel Vassallo
+1  A: 

The answer

<?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);
?>

The test

projects

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 | 
-- +------+

images

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 | 
-- +------+------+

the delete

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

the result

select * from projects;
-- +------+
-- | p_id |
-- +------+
-- |    2 | 
-- |    3 | 
-- +------+

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

works a treat!

macek