2012-06-18 4 views
1

je le suivant SQL Server procédure stockée:procédure stockée SQL Server éviter curseur

BEGIN TRAN 
CREATE TABLE #TempTable (
          SampleOrderID int, 
          SampleOrderNo varchar(512), 
          ChallanNoAndChallanDate varchar(MAX) 
         ) 
CREATE NONCLUSTERED INDEX #IX_Temp2_1 ON #TempTable(SampleOrderID) 

DECLARE 
@SQL as varchar(MAX) 
SET @SQL='  SELECT SampleOrderID, SampleOrderNo FROM SampleOrder WHERE SampleOrderID IN (37808,37805,37767,37571,37745,37772,37843,37394,37909,37905,37903) ' 
INSERT INTO #TempTable (SampleOrderID, SampleOrderNo) 
EXEC (@SQL) 

DECLARE 
@SampleOrderID as int, 
@ChallanNoAndChallanDate as varchar(max) 

DECLARE Cur_AB1 CURSOR GLOBAL FORWARD_ONLY KEYSET FOR   
SELECT SampleOrderID FROM #TempTable 
OPEN Cur_AB1 
FETCH NEXT FROM Cur_AB1 INTO @SampleOrderID 
WHILE(@@Fetch_Status <> -1) 
    BEGIN--2 
     SET @ChallanNoAndChallanDate='' 
     SELECT @ChallanNoAndChallanDate= COALESCE(@ChallanNoAndChallanDate+ ',', '') + CONVERT(VARCHAR(12),ChallanDate,106)+':'+ChallanNo FROM Challan WHERE OrderID [email protected] AND OrderType=2 

     UPDATE #TempTable SET [email protected] WHERE [email protected] 
     FETCH NEXT FROM Cur_AB1 INTO @SampleOrderID 
    END--2 
CLOSE Cur_AB1 
DEALLOCATE Cur_AB1 

SELECT * FROM #TempTable 
DROP TABLE #TempTable 
COMMIT TRAN 

Sortie:

SamID  SamNo ChallanNoAndDaet 
37394 37394 ,31 May 2012:151592 
37571 37571 ,31 May 2012:151580 
37745 37745 ,31 May 2012:151582 
37767 37767 ,30 May 2012:151507,31 May 2012:151576 
37772 37772 ,31 May 2012:151587 
37805 37805 ,31 May 2012:151574 
37808 37808 ,31 May 2012:151573 
37843 37843 ,31 May 2012:151588 
37903 37903 ,31 May 2012:151597 
37905 37905 ,31 May 2012:151596 
37909 37909 ,31 May 2012:151593 

Il fonctionne avec succès pour un petit volume de données mais lorsque je tente de l'exécuter sur Un grand volume (c.-à-d. plus de 500 000 enregistrements) mon interface C# jette l'exception de délai.

Quelqu'un peut-il m'aider à modifier ma procédure stockée pour éviter le curseur?

Merci pour la réponse.

+0

Il est appelé ** procédure stockée ** car il est ** stocké ** dans SQL Server - ce n'est pas un * magasin procédure *, n'a rien à voir avec un * magasin *. –

+1

Je pense que [Mise à jour sur la jointure interne] (http://www.bennadel.com/blog/938-Using-A-SQL-JOIN-In-A-SQL-UPDATE-Statement-Thanks-John-Eric-.htm) est l'approche de ce scénario. – Rab

Répondre

1

Je l'habitude d'utiliser quelque chose comme ce qui suit:

SELECT @SampleOrderID = MIN (SampleOrderID) FROM #TempTable 
WHILE @SampleOrderID IS NOT NULL 
BEGIN 

    SET @ChallanNoAndChallanDate='' 
    SELECT @ChallanNoAndChallanDate= COALESCE(@ChallanNoAndChallanDate+ ',', '') + CONVERT(VARCHAR(12),ChallanDate,106)+':'+ChallanNo FROM Challan WHERE OrderID [email protected] AND OrderType=2 

    UPDATE #TempTable SET [email protected] WHERE [email protected] 

    SELECT @SampleOrderID = MIN (SampleOrderID) FROM #TempTable WHERE SampleOrderID > @SampleOrderID 

END 

Ce code remplacerait les choses du curseur que vous avez.

4

J'utilise ceci pour éviter curseur dans partout où je besoin

DECLARE @num_rows  int 
DECLARE @cnt   int 
DECLARE @selected  int 

DECLARE @table1 TABLE (Id int not null primary key identity(1,1), col1 int) 
INSERT into @table1 (col1) SELECT col1 FROM table2 
SET @[email protected]@ROWCOUNT 

SET @cnt=0 
WHILE @cnt<@num_rows 
BEGIN 
    SET @[email protected]+1 
    SELECT 
     @selected=col1 
     FROM @table1 
     WHERE [email protected] 

    --do your stuff here-- 

END