Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Call Stored Procedure recursively

Posted on 2007-03-28
6
Medium Priority
?
943 Views
Last Modified: 2012-05-05
I am using SQL Server 2000.

I have a Stored Proc that calls itself using a CURSOR. SOmething like:

CREATE Procedure dbo.gui_usp_Delete_ID
      @id int
AS

      --Get a list of non-reference'd child user scenarios
      SELECT
            innerId
      INTO
            #tmpTable
      FROM
            myTable
      WHERE
            id = @id

      --DO what is needed here      
      
      --Recursively delete all the Inner Ids
      DECLARE csrInnerIDs CURSOR
      READ_ONLY
      FOR SELECT innerId FROM #tmpTable

      DECLARE @id int
      OPEN csrInnerIDs

      FETCH NEXT FROM csrInnerIDs INTO @id
      WHILE (@@fetch_status <> -1)
      BEGIN
            IF (@@fetch_status <> -2)
            BEGIN
                  EXEC dbo.gui_usp_Delete_ID @id
            END
            FETCH NEXT FROM csrInnerIDs INTO @id
      END

      CLOSE csrInnerIDs
      DEALLOCATE csrInnerIDs
      
END


And it ofcourse throws an error saying:
A cursor with the name 'csrInnerIDs' already exists.
The cursor is already open.
A cursor with the name 'csrInnerIDs' does not exist.
A cursor with the name 'csrInnerIDs' does not exist.
A cursor with the name 'csrInnerIDs' does not exist.

How do I fix this? Is there a different way to do this recursion?

Thanks
0
Comment
Question by:srinivas_vemla
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
6 Comments
 
LVL 11

Expert Comment

by:Ved Prakash Agrawal
ID: 18809201
hi, can you tell me why you need to execute procedure like this way????
0
 

Author Comment

by:srinivas_vemla
ID: 18809303
My table structure has IDs and innerIDs... InnerIDs are nothing but other IDs used by the original ID... and this inner'ness is not limited to 2 levels... i means the innerIDs can again refer to other innerIDs and so on...

So when I want to delete the original ID, i have to recursively delete even the innerIDs associated with them... So i want to call the SP recursively...
0
 
LVL 23

Assisted Solution

by:Christopher Kile
Christopher Kile earned 800 total points
ID: 18809623
Why not define innerID as a foreign key onto Mytable with ON DELETE CASCADE? or are you doing something other than deleting the entire record?

As an alternative, instead of

DECLARE csrInnerIDs CURSOR READ_ONLY FOR SELECT innerId FROM #tmpTable

you might try:

DECLARE @csrInnerIDs CURSOR

SET @csrInnerIDs = CURSOR READ-ONLY FOR SELECT innerId FROM #tmpTable

Each cursor generated should then have a unique instance name.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 75

Expert Comment

by:Aneesh Retnakaran
ID: 18809670
Replace that cursor with some Table variable


CREATE Procedure dbo.gui_usp_Delete_ID
      @id int
AS

      --Get a list of non-reference'd child user scenarios
      SELECT
            innerId
      INTO
            #tmpTable
      FROM
            myTable
      WHERE
            id = @id

      --DO what is needed here      
      DECLARE @tot int
      --Recursively delete all the Inner Ids
      DECLARE @csrInnerIDs TABLE (i INT IDENTITY, innerId INT)
      INSERT INTO @csrInnerIDs       
      SELECT innerId FROM #tmpTable
      SET @tot = @@ROWCOUNT

 
      WHILE (@tot > 0)
      BEGIN
              SELECT @id = innerId FROM #tmpTable WHERE i = @id
                  EXEC dbo.gui_usp_Delete_ID @id
              SET @tot = @tot -1
      END
END
0
 
LVL 42

Accepted Solution

by:
dqmq earned 1200 total points
ID: 18809683
I think you have more problems with the temp table than with the cursor.  Don't see why you need the temp table, anyway--just select for @ID in the cursor.

But, perhaps a better way is to use add self-referencing foreign key to the table and specify CASCADE DELETE. No programming required!. Put the foreign key on the innerID column referencing the ID column. The idea is that you can then delete the parent and all the children go with it.

Alternatively, you could write a recursive trigger to do the same.
0
 

Author Comment

by:srinivas_vemla
ID: 18811854
I am going the CASCADE way... thanks guys
0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article shows gives you an overview on SQL Server 2016 row level security. You will also get to know the usages of row-level-security and how it works
What if you have to shut down the entire Citrix infrastructure for hardware maintenance, software upgrades or "the unknown"? I developed this plan for "the unknown" and hope that it helps you as well. This article explains how to properly shut down …
Via a live example combined with referencing Books Online, show some of the information that can be extracted from the Catalog Views in SQL Server.
Viewers will learn how to use the SELECT statement in SQL to return specific rows and columns, with various degrees of sorting and limits in place.

618 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question