0
DECLARE @a uniqueidentifier, @b uniqueidentifier, @c datetime, @d numeric(15, 2) 
DECLARE MyCursor CURSOR FOR
SELECT Z.ID, Z.Name, Z.Date, (V1.Credit - V2.Debet) AS Money
FROM dbo.Table1 V1
INNER JOIN dbo.Table1 V2
ON V2.Name = V1.Name AND V2.ID = V1.ID AND V2.Date = V1.Date
INNER JOIN dbo.Table2 Z
ON Z.Name = V1.Name AND Z.ID = V1.ID AND Z.Date = V1.Date
WHERE V1.Date = DATEADD(Day, Z.AllowedDays, V2.Date)  
OPEN MyCursor
FETCH NEXT FROM MyCursor INTO @a, @b, @c, @d
    -- Get stuck here!!!
print 'My Cursor goes ahead'
WHILE @@FETCH_STATUS = 0
BEGIN
...

有人可以解释为什么它会卡在我的案例中吗?我无法理解原因,因为独立 Select 正在自行完成。

4

1 回答 1

2

您实际上需要进入循环,您可以通过在循环内重复 fetch 来执行此操作:

FETCH NEXT FROM MyCursor INTO @a

WHILE @@FETCH_STATUS = 0
BEGIN
    -- Some operations

    FETCH NEXT FROM MyCursor INTO @a
----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
END

否则,这是一个无限循环,不断处理第一行。

顺便说一句,光标很少是正确的答案。也许您应该考虑尝试基于集合的解决方案而不是游标。如果你真的需要一个游标,至少,这样做:

DECLARE MyCursor CURSOR LOCAL FAST_FORWARD FOR

如果查询一直在旋转,那么它可能被阻止了。这可能是由于光标选项,所以尝试LOCAL FAST_FORWARD可能会有所帮助,但它可能不止于此。我们无法猜测您被什么阻止,但您可以自己检查。停止查询,并在该窗口中执行SELECT @@SPID;并记下返回的数字。现在,再次启动游标查询,并打开一个新窗口。运行以下命令(替换x@@SPID数字):

SELECT blocking_session_id, wait_type FROM sys.dm_exec_requests 
  WHERE session_id = x;

DBCC现在,如果您在第一列中获得另一个会话 ID,您可以使用类似的查询和命令查看他们在做什么以及他们阻止您的原因:

SELECT status, command FROM sys.dm_exec_requests
  WHERE session_id = y;

DBCC INPUTBUFFER(y);

(同样,替换y为上一个查询中的会话 ID。)

于 2013-10-24T14:35:06.173 回答