在SELECT语句中没有顶部xxx的TSQL游标无限循环

在SELECT语句中没有顶部xxx的TSQL游标无限循环,tsql,cursor,Tsql,Cursor,我对TSQL游标中的无限循环有一个奇怪的问题。当我不向游标的定义select语句添加TOP 300时,游标将无限循环。下面是代码的一个示例:非常感谢对此问题提供的任何帮助 DECLARE @Done BIT SET @Done = 0 DECLARE cursOut CURSOR LOCAL FAST_FORWARD FOR SELECT --TOP 300 FirstName FirstName ,LastName LastName ,MiddleName M

我对TSQL游标中的无限循环有一个奇怪的问题。当我不向游标的定义select语句添加TOP 300时,游标将无限循环。下面是代码的一个示例:非常感谢对此问题提供的任何帮助

DECLARE @Done BIT
SET @Done = 0

DECLARE cursOut CURSOR LOCAL FAST_FORWARD
FOR
SELECT
    --TOP 300
    FirstName FirstName
    ,LastName LastName
    ,MiddleName MiddleName
    ,Email Email
    ,Address1 Address1
    ,Address2 Address2
    ,City City
    ,[State] [State]
       FROM StagedUsers

OPEN cursOut;

WHILE (@Done = 0)
   BEGIN       
 --Fetch next row
    FETCH NEXT
    FROM cursOut
    INTO ,@v_FirstName
        ,@v_LastName
        ,@v_MiddleName
        ,@v_Email
        ,@v_Address1
        ,@v_Address2
        ,@v_City
        ,@v_State

    IF (@@FETCH_STATUS <> 0)
    BEGIN
        SET @Done = 1
        BREAK
    END

    --if @batch = 0
    BEGIN TRANSACTION

    --process statements
    --updates or insert statements


    --Commit transaction    
    COMMIT TRANSACTION

--End While             
    END 


--CleanUp:
CLOSE cursOut
DEALLOCATE cursOut
谢谢,
Renegrin

首先,我认为您不需要这里的事务,我假定它只执行了一条语句,所以从代码中删除事务

第二,在没有@done标志的情况下进行操作,这会让人困惑,这可能不是问题

DECLARE @v_FirstName VARCHAR(500),@v_LastName VARCHAR(500),@v_MiddleName VARCHAR(500),@v_Email VARCHAR(500),@v_Address1 VARCHAR(500),@v_Address2 VARCHAR(500),@v_City VARCHAR(500),@v_State VARCHAR(500)

DECLARE cursOut CURSOR FAST_FORWARD FOR
SELECT FirstName FirstName,LastName LastName,MiddleName MiddleName,Email Email,Address1 Address1,Address2 Address2,City City,[State] [State]
FROM StagedUsers

OPEN cursOut;

FETCH NEXT FROM cursOut INTO @v_FirstName,@v_LastName,@v_MiddleName,@v_Email,@v_Address1,@v_Address2,@v_City,@v_State

declare @i int = 1

WHILE @@FETCH_STATUS = 0
BEGIN       
print cast(@i as varchar(10))

--> statement here

FETCH NEXT FROM cursOut INTO @v_FirstName,@v_LastName,@v_MiddleName,@v_Email,@v_Address1,@v_Address2,@v_City,@v_State

set @i = @i + 1     
END 

CLOSE cursOut
DEALLOCATE cursOut
是否要更新光标指向的当前行?如果是这样,就有办法做到这一点


表上有索引吗?您可以发布更新查询吗?

您是否插入了要从中选择的同一个表?当然,如果您有很多记录,您在任何情况下都不想使用cusor。你为什么要做这样的事?对于游标所能做的大多数事情,都有基于集合的解决方案,它们将运行得更快。你想干什么?我怀疑你是在一个无限循环中,一个游标很容易需要一天或更长的时间来处理大量记录。StageUsers表中有多少行?你看过执行计划了吗?处理一条记录需要多长时间?目前只有300条记录需要2分钟。如果我有10万美元,我需要18分钟才能提供最重要的报表。如果我不这样做,它将永远循环。我无法直接查看执行计划,因为它位于SSIS包中,并且是远程的。我从来没有以这种方式实现过这个过程,我将它设置为基于集合的,但我继承了这个实现。2分钟300条记录?这不是一个无限循环,只是需要很长时间。如果你把它放几天,你要么会看到它完成,要么会用完临时空间。我没有看到无限循环的迹象,只是一个非常低效的过程。