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 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 に答える