views:

84

answers:

2

Hi There,

I have the following tables, with these keys in my database:

bookings session_id

sessions session_id course_id

courses course_id

I want to create a query to delete all date relating to a single course (course_id). For example if I wanted delete course_id=10, I would want any sessions with course_id=10 to be deleted, in addition any bookings associated with any of these sessions need to be deleted too.

Is this possible? what is the best way to approach it? (I'm writing this in PHP.)

Any help much appreciated!

+3  A: 

I think the best way would be to configure the tables adding proper foreign keys (you'll have to use InnoDB for this to actually work in mysql) and setting the behavior of the FKs to 'ON DELETE CASCADE'. This way, when you delete something from the courses table, the related bookings and sessions will be deleted automatically.

Some linksies:

Adriano Varoli Piazza
+4  A: 

MySQL supports multi-table deletes:

DELETE FROM BOOKINGS 
 USING BOOKINGS JOIN SESSIONS JOIN COURSES
 WHERE BOOKINGS.session_id = SESSIONS.session_id
   AND SESSIONS.course_id = COURSES.course_id
   AND COURSES.course_id = ?

Another alternative would be to use stored procedure, and process the deletions in proper order:

  1. BOOKINGS

    DELETE FROM BOOKINGS
     WHERE EXISTS(SELECT NULL
                    FROM SESSIONS s 
                   WHERE s.session_id = session_id
                     AND s.course_id = ?)
    
  2. SESSIONS

    DELETE FROM SESSIONS
     WHERE EXISTS(SELECT NULL
                    FROM COURSES c
                   WHERE c.course_id = course_id
                     AND c.course_id = ?)
    
  3. COURSES

    DELETE FROM COURSES
     WHERE course_id = ?
    
OMG Ponies
does my proposed solution have any drawbacks apart from depending on using the InnoDB engine? Also, it's _id for the keys.
Adriano Varoli Piazza
OMG Ponies
Hi There,Thanks for the response, I am attempting to use the first multi delete method:DELETE FROM bookings, sessions, courses USING bookings JOIN sessions JOIN courses WHERE bookings.session_id=sessions.session_id AND sessions.course_id=courses.course_id AND courses.course_id="13"This doesn't seem to be working - is my syntax correct?-Thanks!
Fred
If you don't use transactions, *don't use a sequence of related actions*.
bart
@bart: Yes, which is why I mentioned "stored procedure".
OMG Ponies
@Fred: What error are you getting? Dealing with this via comments isn't the most ideal way.
OMG Ponies
I'm getting the following:#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM bookings, sessions, courses USING bookings JOIN sessions JOIN courses WHERE' at line 1Sorry, I agree, not sure where else to post this other than comments?
Fred
@Fred: Remove the `FROM`, I'll update my answer.
OMG Ponies
Hi, Thanks again for the help... I'm now using: 'DELETE bookings, sessions, courses USING bookings JOIN sessions JOIN courses WHERE bookings.session_id=sessions.session_id AND sessions.course_id=courses.course_id AND courses.course_id="10"'But still getting the following: '#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'USING bookings JOIN sessions JOIN courses WHERE bookings.session_id=sessions.ses' at line 1' ?
Fred
@OMG Ponies I don't get exactly who would not necessarily know about the behavior: if it's the end user, he's as likely to be unable to read the code. If it's the programmer, he could study the db schema before twiddling random bits, shouldn't he?Also, backups are delicious.
Adriano Varoli Piazza
@Adriano Varoli Piazza: Any shop where there's more than one person able to make changes to the database. It's the same rationale why triggers aren't liked - there's now multiple places to check for configuration to know why something happened because something was done "auto-magically". I agree co-workers should be diligent, but they aren't all as familiar with the technology as you are.
OMG Ponies
@Fred perhaps you have to use the alternative syntax? DELETE bookings, sessions, courses FROM bookings INNER JOIN sessions ON bookings.session_id = session.session_id INNER JOIN courses ON sessions.course_id = courses.course_id WHERE courses.course_id = '10'
Adriano Varoli Piazza
@Fred: Missed your comment, update answer.
OMG Ponies
@OMG Ponies that argument sounds very shallow to me: "We might hire crappy coders, so we can't do things the proper (to me at least) way. Let's enforce the way through code". This is not 'hiding' or 'automagic'. This is stated clearly in the DB schema, which one should learn before coding their way into a paperbag. To sum up: I hadn't ever heard that CASCADEs were not recommended practice before. Could you cite?
Adriano Varoli Piazza
@Adriano Varoli Piazza: People don't all share the same skill sets, and centralization of configuration is a principle every app strives for. Just because you haven't heard of a best practice, doesn't mean others don't share it. You could ask the question on SO.
OMG Ponies
Hi Guys, Thanks ever so much for all your help - think I've got it working how I wanted now!..
Fred