Solved

Call Stored Procedure recursively

Posted on 2007-03-28
6
931 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
Ransomware-A Revenue Bonanza for Service Providers

Ransomware – malware that gets on your customers’ computers, encrypts their data, and extorts a hefty ransom for the decryption keys – is a surging new threat.  The purpose of this eBook is to educate the reader about ransomware attacks.

 
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

Technology Partners: 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!

Question has a verified solution.

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

Suggested Solutions

Let's review the features of new SQL Server 2012 (Denali CTP3). It listed as below: PERCENT_RANK(): PERCENT_RANK() function will returns the percentage value of rank of the values among its group. PERCENT_RANK() function value always in be…
For both online and offline retail, the cross-channel business is the most recent pattern in the B2C trade space.
Via a live example, show how to extract information from SQL Server on Database, Connection and Server properties
Viewers will learn how to use the UPDATE and DELETE statements to change or remove existing data from their tables. Make a table: Update a specific column given a specific row using the UPDATE statement: Remove a set of values using the DELETE s…

696 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