Solved

Call Stored Procedure recursively

Posted on 2007-03-28
6
936 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 200 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
NEW Veeam Agent for Microsoft Windows

Backup and recover physical and cloud-based servers and workstations, as well as endpoint devices that belong to remote users. Avoid downtime and data loss quickly and easily for Windows-based physical or public cloud-based workloads!

 
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 300 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

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

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

For both online and offline retail, the cross-channel business is the most recent pattern in the B2C trade space.
Recently we ran in to an issue while running some SQL jobs where we were trying to process the cubes.  We got an error saying failure stating 'NT SERVICE\SQLSERVERAGENT does not have access to Analysis Services. So this is a way to automate that wit…
This video shows, step by step, how to configure Oracle Heterogeneous Services via the Generic Gateway Agent in order to make a connection from an Oracle session and access a remote SQL Server database table.
Viewers will learn how the fundamental information of how to create a table.

718 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