Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid Database Cursor in SQL Server

I have a bit of a puzzle (at least for me) which I am hoping is mostly because I am not yet an SQL master of the universe. Basically I have three tables:

Table A, Table B, and Table C.

Table C has a FK (Foriegn Key) to Table B, which has FK to Table A. (Each of these is many to one)

I need to remove an entry from Table A and of course all of it's corresponding entries from Tables B and C. In the past I've used a cursor to do this, selecting all the entries in Table B and cycling through each one to delete all their corresponding entries in Table C. Now this works - and has been working fine, but I suspect/hope there is a better way to achieve this effect without the use of cursors. So that's my question - how can I do this without using a cursor, or can it be done?

(Please let me know if I haven't been clear - I'll try to fix up the question).

like image 703
Streklin Avatar asked Sep 28 '09 14:09

Streklin


People also ask

Why should we avoid cursor in SQL Server?

Cursors could be used in some applications for serialized operations as shown in example above, but generally they should be avoided because they bring a negative impact on performance, especially when operating on a large sets of data.

How do you stop a cursor in SQL?

EXEC SQL CLOSE cursor-name END-EXEC. If you processed the rows of a result table and you do not want to use the cursor again, you can let the system close the cursor. The system automatically closes the cursor when: A COMMIT without HOLD statement is issued and the cursor is not declared using the WITH HOLD clause.

What can I use instead of cursor in SQL Server?

Temporary tables have been in use for a long time and provide an excellent way to replace cursors for large data sets. Just like table variables, temporary tables can hold the result set so that we can perform the necessary operations by processing it with an iterating algorithm such as a 'while' loop.

Why do we need database cursor?

Cursors are used by database programmers to process individual rows returned by database system queries. Cursors enable manipulation of whole result sets at once. In this scenario, a cursor enables the sequential processing of rows in a result set.


2 Answers

Declare your FOREIGN KEYs as ON DELETE CASCADE

like image 98
Quassnoi Avatar answered Nov 15 '22 00:11

Quassnoi


You could do this a couple ways...

  • You could just use cascading deletes on your foreign keys.

CREATE TABLE TableB
    (FKColumn INT,
     CONSTRAINT MyFk FOREIGN KEY (FKColumn) 
         REFERENCES TableA(PKColumn) ON DELETE CASCADE)
  • You could use delete triggers on each table to delete the related records.

CREATE TRIGGER cascade_triggerA
    ON TableA 
    FOR DELETE
AS 
BEGIN

    DELETE TableB
    FROM   TableB JOIN DELETED ON TableB.FKColumn = DELETED.PKColumn

END

CREATE TRIGGER cascade_triggerB 
    ON TableB 
    FOR DELETE
AS 
BEGIN

    DELETE TableC
    FROM   TableC JOIN DELETED ON TableC.FKColumn = DELETED.PKColumn

END
  • If you're using MS SQL server, you could also use INSTEAD OF DELETE triggers. In this case, you'd create the trigger just on TableA - and in the trigger put all of the logic to delete the records from all 3 tables.

In any of the above cases, you'd just delete the record from table A, and let the cascading and triggers take care of the rest.

like image 25
Scott Ivey Avatar answered Nov 14 '22 23:11

Scott Ivey