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
 SQL Server 2005 Forums
 Transact-SQL (2005)
 Recursive sp call and cursors

Author  Topic 

moodi_z
Starting Member

38 Posts

Posted - 2009-07-20 : 04:59:58
Hi,
I'm trying to build a recursive stored procedure but I faced a problem with using cursor ofcourse because I can't declare the same name each time.
Error: "A cursor with the name 'Cursor1' already exists."


ALTER PROCEDURE [dbo].[sp_RetrieveRecordGenealogy]
@BarcodeUID NVARCHAR(50),
@Err_Description AS NVARCHAR(100) OUTPUT
AS
BEGIN
SET NOCOUNT ON;

SET @Err_Description = ''

IF @BarcodeUID = '' OR @BarcodeUID IS NULL
BEGIN
SELECT @Err_Description = '001 # ' + ErrMessage FROM Tbl_ErrMessages WHERE ErrNumber = 1
RETURN
END

ELSE IF NOT EXISTS (SELECT BarcodeUID FROM Tbl_RawMaterial WHERE BarcodeUID = @BarcodeUID) AND
NOT EXISTS (SELECT BarcodeUID FROM Tbl_BagsPallet WHERE BarcodeUID = @BarcodeUID) AND
NOT EXISTS (SELECT BarcodeUID FROM Tbl_Rolls WHERE BarcodeUID = @BarcodeUID)
BEGIN
SELECT @Err_Description = '015 # ' + ErrMessage FROM Tbl_ErrMessages WHERE ErrNumber = 15
RETURN
END


IF OBJECT_ID('TMP','U') IS NULL
CREATE TABLE TMP (
[BarcodeUID] [nvarchar](50) NULL,
[TimeStamp] [datetime] NULL,
[TransactionType] [nvarchar](50) NULL,
[Weight] [real] NULL,
[Remarks] [nvarchar](50) NULL,
[WIPID] [nvarchar](50) NULL,
[WIPSID] [nvarchar](50) NULL,
[ReceivingBarcodeUID] [nvarchar](50) NULL,
[WarehouseID] [nvarchar](50) NULL,
[LocationID] [nvarchar](50) NULL,
[IssuingStationID] [nvarchar](50) NULL,
[Meters] [real] NULL)

INSERT INTO TMP
SELECT --DISTINCT
BarcodeUID
,[TimeStamp]
,TransactionType
,Weight
,Remarks
,WIPID
,WIPSID
,ReceivingBarcodeUID
,WarehouseID
,LocationID
,IssuingStationID
,Meters
FROM Tbl_BarcodeTransactions
WHERE ReceivingBarcodeUID = @BarcodeUID

DECLARE @ReceivingBarcodeUID AS NVARCHAR(50),
@ERR AS NVARCHAR(100),
@Barcode NVARCHAR(50)

-- SELECT @Barcode = BarcodeUID
-- FROM Tbl_BarcodeTransactions
-- WHERE ReceivingBarcodeUID = @BarcodeUID

DECLARE Cursor1 SCROLL CURSOR FOR SELECT BarcodeUID FROM TMP
OPEN Cursor1
FETCH FIRST FROM Cursor1 INTO @Barcode

WHILE @@FETCH_STATUS = 0
BEGIN

--IF (@BarcodeUID IS NOT NULL) AND (@BarcodeUID <> '')
IF EXISTS (SELECT * FROM Tbl_BarcodeTransactions WHERE ReceivingBarcodeUID = @Barcode)
EXEC sp_RetrieveRecordGenealogy @Barcode,
@Err_Description = @Err OUTPUT

FETCH NEXT FROM Cursor1 INTO @Barcode

-- ELSE
-- BEGIN
-- SELECT * FROM TMP
-- DROP TABLE TMP
-- END
END

CLOSE Cursor1;
DEALLOCATE Cursor1;

SELECT * FROM TMP
DROP TABLE TMP

END



What can I do in such a case!

Thanks in advance.

saran_d28
Starting Member

36 Posts

Posted - 2009-07-20 : 05:37:10
Hi,
close & deallocate the cursor with in the if condition

DECLARE CURSOR1 FOR SELECT * FROM TMP
OPEN CURSOR1
FETCH FIRST FROM CURSOR1
WHILE @@FETCH_STATUS = 0
BEGIN
IF EXISTS(SELECT ..)
BEGIN
CLOSE CURSOR1
DEALLOCATE CURCOR1
EXEC MYPROC
END
ELSE
BEGIN
FETCH NEXR FROM CORSOR1
SELECT * FROM TMP
DROP TABLE TMP
END
CLOSE CURSOR1
DEALLOCATE CURSOR1


Go to Top of Page

moodi_z
Starting Member

38 Posts

Posted - 2009-07-20 : 06:46:28
Ya, I tried that before and I got:

Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32).
Go to Top of Page

saran_d28
Starting Member

36 Posts

Posted - 2009-07-20 : 08:30:13
Yes, We cant nesting the SPs more than 32 times
Go to Top of Page

moodi_z
Starting Member

38 Posts

Posted - 2009-07-21 : 00:39:42
Strange! Thanks anyway.
Go to Top of Page

moodi_z
Starting Member

38 Posts

Posted - 2009-07-21 : 01:09:46
I think that I'm reaching that limit because of closing the cursor.. the @@FETCH_STATUS never comes to zero and it really return a table with 32 rows (and then falls), the first row gets the first value and it's ok, but others are a duplicate for the second value.. the fetch next doesn't effect on it!!!!!!!!!!
Go to Top of Page

Transact Charlie
Master Smack Fu Yak Hacker

3451 Posts

Posted - 2009-07-21 : 06:10:29
You are searching a tree?

Ditch the stored proc (and the cursor) and have a look at recursive CTE in books online.

You get 32767 levels max recursion and it will outperform your procedure. (probably by a factor of 10 at least)

Recursive CTE are hard to get your head around but if you post some sample data and desired results you will get some good, efficient suggestions.


Charlie
===============================================================
Msg 3903, Level 16, State 1, Line 1736
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION
Go to Top of Page

moodi_z
Starting Member

38 Posts

Posted - 2009-07-22 : 02:41:20
Woooooooooooooooooooooow, amazing..

ALTER PROCEDURE [dbo].[sp_RetrieveRecordGenealogy_Test]
@BarcodeUID NVARCHAR(50),
@Err_Description AS NVARCHAR(100) OUTPUT
AS
BEGIN
SET NOCOUNT ON;

SET @Err_Description = '';

IF @BarcodeUID = '' OR @BarcodeUID IS NULL
BEGIN
SELECT @Err_Description = '001 # ' + ErrMessage FROM Tbl_ErrMessages WHERE ErrNumber = 1
RETURN
END;

ELSE IF NOT EXISTS (SELECT BarcodeUID FROM Tbl_RawMaterial WHERE BarcodeUID = @BarcodeUID) AND
NOT EXISTS (SELECT BarcodeUID FROM Tbl_BagsPallet WHERE BarcodeUID = @BarcodeUID) AND
NOT EXISTS (SELECT BarcodeUID FROM Tbl_Rolls WHERE BarcodeUID = @BarcodeUID)
BEGIN
SELECT @Err_Description = '015 # ' + ErrMessage FROM Tbl_ErrMessages WHERE ErrNumber = 15
RETURN
END;


-----------------------------------------------------------------------------------------------

/*
* Moodi:
* Using CTE (common table expression) to implement recursive query
*/

WITH BarcodeTransactions (
BarcodeUID
,[TimeStamp]
,TransactionType
,Weight
,Remarks
,WIPID
,WIPSID
,ReceivingBarcodeUID
,WarehouseID
,LocationID
,IssuingStationID
,Meters
,Level)
AS
(
-- Anchor member definition
SELECT
A.BarcodeUID
,A.[TimeStamp]
,A.TransactionType
,A.Weight
,A.Remarks
,A.WIPID
,A.WIPSID
,A.ReceivingBarcodeUID
,A.WarehouseID
,A.LocationID
,A.IssuingStationID
,A.Meters
,0 AS Level
FROM Tbl_BarcodeTransactions AS A
WHERE A.ReceivingBarcodeUID = @BarcodeUID

UNION ALL

-- Recursive member definition
SELECT
A.BarcodeUID
,A.[TimeStamp]
,A.TransactionType
,A.Weight
,A.Remarks
,A.WIPID
,A.WIPSID
,A.ReceivingBarcodeUID
,A.WarehouseID
,A.LocationID
,A.IssuingStationID
,A.Meters
,Level + 1
FROM Tbl_BarcodeTransactions AS A
INNER JOIN BarcodeTransactions AS B
ON A.ReceivingBarcodeUID = B.BarcodeUID

)

-- Statement that executes the CTE
SELECT * FROM BarcodeTransactions

END

Thank you very much ;)
Go to Top of Page

Transact Charlie
Master Smack Fu Yak Hacker

3451 Posts

Posted - 2009-07-22 : 04:56:47
NP you did the legwork!


Charlie
===============================================================
Msg 3903, Level 16, State 1, Line 1736
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION
Go to Top of Page
   

- Advertisement -