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.
| 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 ASBEGIN 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 TMPENDWhat 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 conditionDECLARE CURSOR1 FOR SELECT * FROM TMPOPEN CURSOR1FETCH FIRST FROM CURSOR1WHILE @@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 ENDCLOSE CURSOR1DEALLOCATE CURSOR1 |
 |
|
|
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). |
 |
|
|
saran_d28
Starting Member
36 Posts |
Posted - 2009-07-20 : 08:30:13
|
| Yes, We cant nesting the SPs more than 32 times |
 |
|
|
moodi_z
Starting Member
38 Posts |
Posted - 2009-07-21 : 00:39:42
|
| Strange! Thanks anyway. |
 |
|
|
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!!!!!!!!!! |
 |
|
|
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 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
 |
|
|
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 ASBEGIN 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 BarcodeTransactionsENDThank you very much ;) |
 |
|
|
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 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
 |
|
|
|
|
|
|
|