tags:

views:

141

answers:

5

Cascading deletes aren't setup on this particular database. Just wondering if there's a way to do it in one swipe that's more efficient than running two separate statements.

+4  A: 

No.

You could do two statements on a single command:

DELETE FROM ChildTable; DELETE FROM ParentTable;

But in effect that is two statements.

or

You could put a trigger on the ChildTable that deletes parent records.

Neither meets your criteria.

Nissan Fan
+1  A: 

Should be in a transaction - it may be less efficient but much better for data integrity

BEGIN TRAN
DELETE FROM ChildTable WHERE safetycatch=0
DELETE FROM ParentTable WHERE safetycatch=0
COMMIT TRAN

Edit - if you really want to use only one statement then you could create a stored procedure e.g.

CREATE PROCEDURE DeleteBoth AS
    BEGIN TRAN
    DELETE FROM ChildTable WHERE safetycatch=0
    DELETE FROM ParentTable WHERE safetycatch=0
    --ERROR HANDLING IF STUFF GOES WRONG THEN ROLLBACK TRAN
    COMMIT TRAN
GO

then you can run it in one line from then on with

EXEC DeleteBoth

With a cached execution plan, I imagine the performance difference would be negligible compared to a cascading delete as that's pretty much what's going on behind the scenes anyway.

wefwfwefwe
Caution should be used on these examples. Delete from ChildTable and Delete from ParentTable will remove ALL entries on those tables. Remember to throw a WHERE statement in your queries as appropiate to avoid this issue.
Chris
Never write a proc that has a commit tran without a way to trap errors and rollback if there are any. Also Chris is right, putting an example of deletes with no where clauses up is downright dangerous.
HLGEM
I would have hoped that was obvious... added where clauses and error handling pseudocode anyway. Now stop downvoting me!
wefwfwefwe
A: 

As Nissan Fan mentions, triggers would do it. As wefwfwefwe suggests, use a transaction if it has to be all-or-nothing.

Depending on how desperate you are, you can combine both in an over-complex way to do it with a single statement issued to the database:

  1. Build a view on a join of the tables.
  2. Add an INSTEAD OF trigger on it, coded to drop the appropriate rows from both tables. Not really recommended, but you could do it.
Philip Kelley
+1  A: 

Yes, but only if you define the foreign key relationship and use the ON DELETE CASCADE option.

Everything else will require two statements, even if the statements happen to be in the same transaction.

Joel Coehoorn
A: 

Normally there is a good reason for not setting up cascading deletes (often having to do with blocking and locks). Since they are not set up you need to write separate delete statements for all child and parent tables yourself. I would suggest the best way is in a stored proc using transactions as you do not want to do partial deletes if you care about the integrity of your data. Make sure to have error trapping and rollbacks.

HLGEM