動態游標 (DYNAMIC CURSOR) 反映基礎資料的所有變更 (INSERT/UPDATE/DELETE),游標開啟後的資料異動即時可見,適合需即時同步的場景,但開銷較大。
DECLARE @cursor_name VARCHAR(36), @str NVARCHAR(4000);
DECLARE @ckbm VARCHAR(20);
-- 1. 產生唯一游標名稱
SELECT @cursor_name = NEWID();
-- 2. 動態建立游標 (注意雙引號跳脫)
EXEC('DECLARE [' + @cursor_name + '] CURSOR DYNAMIC FOR SELECT f_ckbm FROM tbda_ck');
-- 3. 開啟游標
EXEC('OPEN [' + @cursor_name + ']');
-- 4. 設定 FETCH 動態 SQL (使用 sp_executesql 繫結輸出參數)
SET @str = N'FETCH NEXT FROM [' + @cursor_name + '] INTO @ckbm';
-- 5. 首次擷取
EXEC sp_executesql @str, N'@ckbm VARCHAR(20) OUTPUT', @ckbm OUTPUT;
-- 6. 迴圈處理
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @ckbm; -- 實際業務邏輯替換 PRINT
-- 後續擷取
EXEC sp_executesql @str, N'@ckbm VARCHAR(20) OUTPUT', @ckbm OUTPUT;
END
-- 7. 關閉並釋放游標
EXEC('CLOSE [' + @cursor_name + ']');
EXEC('DEALLOCATE [' + @cursor_name + ']');
NEWID() 避免同一連線多個動態游標名稱衝突。FETCH ... INTO @變數 需透過 sp_executesql 繫結 OUTPUT 參數,普通 EXEC 無法取回值。CLOSE 釋放鎖定 → DEALLOCATE 釋放記憶體結構,否則洩漏資源。CREATE PROCEDURE usp_GetDynamicCursor
@Cursor CURSOR VARYING OUTPUT
AS
BEGIN
SET @Cursor = CURSOR DYNAMIC FOR
SELECT f_ckbm FROM tbda_ck;
OPEN @Cursor;
END;
GO
-- 呼叫端
DECLARE @MyCursor CURSOR;
EXEC usp_GetDynamicCursor @MyCursor OUTPUT;
FETCH NEXT FROM @MyCursor INTO @ckbm;
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @ckbm;
FETCH NEXT FROM @MyCursor INTO @ckbm;
END
CLOSE @MyCursor;
DEALLOCATE @MyCursor;
此法較簡潔,適用於固定查詢邏輯封裝於 SP 內。
FAST_FORWARD (唯讀、順向、最佳化) 或靜態游標 (STATIC) 複製快照。WHILE EXISTS (SELECT 1 FROM ...) 配合 TOP (1) 模式替代游標。