【问题标题】:SQL Server stored procedure avoid cursorSQL Server 存储过程避免游标
【发布时间】:2013-09-02 16:55:56
【问题描述】:

我有以下 SQL Server 存储过程:

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 =@SampleOrderID AND OrderType=2

        UPDATE #TempTable SET ChallanNoAndChallanDate=@ChallanNoAndChallanDate WHERE SampleOrderID=@SampleOrderID   
        FETCH NEXT FROM Cur_AB1 INTO @SampleOrderID
    END--2
CLOSE Cur_AB1
DEALLOCATE Cur_AB1

SELECT * FROM #TempTable
DROP TABLE #TempTable
COMMIT TRAN 

输出:

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

它适用于少量数据,但是当我尝试在大量数据(即超过 500,000 条记录)上执行它时,我的 C# 接口抛出超时异常。

谁能帮我编辑我的存储过程以避免光标?

感谢您的回复。

【问题讨论】:

  • 它被称为 stored 过程,因为它 stored 在 SQL Server 中 - 它不是 store 过程,不是与商店有任何关系。
  • 我认为Update on Inner join 是这种情况的方法。

标签: sql-server


【解决方案1】:

我用它来避免光标出现在我需要的任何地方

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 @num_rows=@@ROWCOUNT

SET @cnt=0
WHILE @cnt<@num_rows
BEGIN
    SET @cnt=@cnt+1
    SELECT 
        @selected=col1
        FROM @table1
        WHERE Id=@cnt

    --do your stuff here--

END

【讨论】:

    【解决方案2】:

    我通常使用类似以下的东西:

    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 =@SampleOrderID AND OrderType=2
    
       UPDATE #TempTable SET ChallanNoAndChallanDate=@ChallanNoAndChallanDate WHERE SampleOrderID=@SampleOrderID   
    
       SELECT @SampleOrderID = MIN (SampleOrderID) FROM #TempTable WHERE SampleOrderID > @SampleOrderID 
    
    END
    

    此代码将替换您拥有的光标内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-08
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      相关资源
      最近更新 更多