Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 Other Forums
 Other Topics
 Multiple DELETEs *NOT* using Cursors / Temp Tables

Author  Topic 

tjmojo
Starting Member

8 Posts

Posted - 2002-11-28 : 14:50:02
Yes, I am working on Thanksgiving. Lets see who else.

Question: Is there a solution to perform deletes on multiple tables based on the same complex rules without using Cursors or Temporary Tables?

Details: This is a problem primarily about elegance in design and secondarily about performance: How to make something faster that currently takes virtually no time to process?

Assume a table of some entity and another table that references it:

Entity Table (entityID [Primary Key], entityData)
Group Table (groupID, FK_entityID, groupData)
FK_entityID references entityID


The foreign key relationship is enforced as a constraint and updates to entityID are cascaded (propagated / escalated). Deletes, however, are not cascaded, because some (not so smart) user/developer/dba might delete entities and the associated groups, which others might expect never to be deleted. So the entities currently cannot be deleted unless all referencing groups are removed 'manually' beforehand.

The problem now is that the application (which is smarter then most people) NEEDS to delete entities. Assume we want to delete based on some rules:
SELECT
entityID
WHERE
(some rules to select entities to be deleted)
TWO(!!) delete statements would have to be written, one for the group table (first) and then for the entity table.
DELETE
group
WHERE
FK_entityID ...

DELETE
entity
WHERE
entityID ...
Am I correct here? There are no multiple table deletes in a single delete statement, right? So it means, I either loop through the list of entities to be deleted using a CURSOR (argh! – but current solution) or put the list of entities in a temp table (also argh!) and use the temp table either as derived table or sub-query in both delete statements. Theoretically, I could run the select statement to get the list of entities to be deleted for each delete statement, but the rules can be quite complex (involving sub-queries) and I would have to change it in two places every time the rules change.

So, is there a solution to perform deletes on multiple tables based on the same complex rules without using Cursors or Temporary Tables?

The reason that I care about this is that this 'maintenance' procedure is called very frequently to 'maintain' some level of integrity in an environment that, as a whole, lacks consistency. I want the fastest solution possible, so I can call this 10 times a second or more often without a worry. The number of entityIDs matching the delete rules is usually very small (less than 10). Any solution should avoid triggers and similar features.

Thanks for the help in advance.

Merkin
Funky Drop Bear Fearing SQL Dude!

4970 Posts

Posted - 2002-11-28 : 17:14:36
Hi

I am working, but I am in another country. The Internet actually works outside the USA too

If you have SQL 2000 you can use "cascading deletes". These will delete rows in foreign key tables automatically. Look up Books Online for the details.

However, If you can bring yourself to write two queries, I would do it that way. This is your business data we are talking about, I personally prefer things only get deleted when I explicitly delete them.


Damian
Go to Top of Page

nr
SQLTeam MVY

12543 Posts

Posted - 2002-11-29 : 07:00:54
The key is to define your database structure correctly.
The stored procedures that are used to access that structure will then take care of everything needed to maintain the integrity.

You can then implement cascading deletes or triggers or not as you wish - doesn't affect the application which just says 'delete this entity' the SP does the delete.
Maintenence becomes easy because if you find that requirements change and your structure doesn't fit you just have to change the SP to fit the new structure - it still deletes the entity.
If you want to delete a number of entities in one process then you have a choice. You can keep the entity encapsulation by passing a list (e.g. temp table) to the procedure (no change to the delete SP for changes in rules) or you can compromise the design by including the selection criteria with the delete (need to change the SP for changes in rules and also implement the structure in any other entity delete processes)

begin tran
delete group where ...
if @@error ...
delete entity where ...
if @@error ...
commit tran

Note that the temp table may end up the fastest of all these solutions - or maybe a permanent table with spid as the key.

==========================================
Cursors are useful if you don't know sql.
DTS can be used in a similar way.
Beer is not cold and it isn't fizzy.
Go to Top of Page

tjmojo
Starting Member

8 Posts

Posted - 2002-12-05 : 11:19:12
I should have made clear that my question was regarding the possibility of NOT using loops through temp tables or with cursors. Can I delete rows in multiple tables with some form of DELETE ... FROM ... in SQL Server?

Go to Top of Page

robvolk
Most Valuable Yak

15732 Posts

Posted - 2002-12-05 : 11:57:54
You don't need to loop anything, even with temp tables. There is no reason NOT to use temp tables for this kind of operation. If you place only the key values in a temp table (even if it only has one column), you can JOIN the temp table to the group and entity tables when performing the DELETE. You can modify the SELECT criteria at your leisure to accommodate the business rules; once that SELECT is perfected you use it as a source to populate the temp table with the values you need to DELETE.

You still need one DELETE statement per table, you can't delete from more than one table at a time.

This thread has the syntax for DELETE with a JOIN:

http://www.sqlteam.com/Forums/topic.asp?TOPIC_ID=22168

Also look in Books Online for more DELETE syntax rules.

Go to Top of Page

jsmith8858
Dr. Cross Join

7423 Posts

Posted - 2002-12-05 : 12:08:41
Assuming you can determine which ID's in the main table need to be deleted with a SELECT and a WHERE -- as you mentioned -- you could just delete records from the other table like:

DELETE FROM Table2 WHERE ID IN (SELECT ID From Table1 WHERE blah blah)

and then just

DELETE FROM Table1 WHERE Blah blah

no temp tables, no cursors.

- Jeff
Go to Top of Page
   

- Advertisement -