首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

SQL Server 游標完整指南:從基礎語法到分頁存儲過程重構

     編輯:MySQL 綜合教學

為什麼需要游標?

集合操作 (Set-based) 是 SQL 強項,但偶爾需要 逐行處理:複雜業務邏輯、動態 SQL 構建、跨表依賴計算等。游標提供結果集指針,支援定位、搜索、修改當前行。

游標分類

維度選項說明
作用域LOCAL / GLOBAL預設 GLOBAL,批次間可見;LOCAL 僅當前批次
移動方向FORWARD_ONLY / SCROLL預設僅向後;SCROLL 支援 FIRST/LAST/NEXT/PRIOR/ABSOLUTE/RELATIVE

標準五步法

-- 1. 宣告
DECLARE cur_name CURSOR [LOCAL|GLOBAL] [FORWARD_ONLY|SCROLL] FOR SELECT ...;

-- 2. 開啟
OPEN cur_name;

-- 3. 讀取 (FETCH)
FETCH NEXT FROM cur_name INTO @var1, @var2...;
WHILE @@FETCH_STATUS = 0
BEGIN
    -- 處理邏輯
    FETCH NEXT FROM cur_name INTO @var1, @var2...;
END

-- 4. 關閉
CLOSE cur_name;

-- 5. 釋放
DEALLOCATE cur_name;

進階場景實戰

SCROLL 游標 + 多批次共享 (GLOBAL)

DECLARE CURSOR_2 CURSOR SCROLL FOR SELECT xingming, nicheng, xingbie FROM yiren;
-- 批次 1:絕對定位第 4 行
FETCH ABSOLUTE 4 FROM CURSOR_2 INTO @xingming, @nicheng, @xingbie;
-- 批次 2:同一游標繼續定位第 5 行
FETCH ABSOLUTE 5 FROM CURSOR_2 INTO @xingming, @nicheng, @xingbie;
-- 最後釋放
DEALLOCATE CURSOR_2;

游標嵌套 (慎用,性能殺手)

外層遍歷演出表,內層按演出 ID 查詢藝人。原則:能用 JOIN/子查詢/窗口函數解決的絕不嵌套游標。

游標變量 (類強類型)

DECLARE @c1 CURSOR;
SET @c1 = CURSOR FOR SELECT xingming FROM yiren;
OPEN @c1;
FETCH NEXT FROM @c1 INTO @xingming;
-- ...
CLOSE @c1; DEALLOCATE @c1;

實戰重構:分頁存儲過程改用 SCROLL 游標

原方案:動態 SQL + OFFSET/FETCH (或舊版 ROW_NUMBER()),每頁重掃。
新方案:FAST_FORWARD 或 SCROLL 游標定位起始行,僅讀取頁大小行數:

DECLARE @start INT = @currentpage * @pagesize + 1;
SET @sql = 'DECLARE cur_page CURSOR SCROLL FOR SELECT * FROM ' + @tablename + ' ORDER BY ' + @idname;
EXEC(@sql);
OPEN cur_page;
FETCH RELATIVE @start FROM cur_page; -- 直接跳轉
-- 讀取 @pagesize 行
WHILE @@FETCH_STATUS = 0 AND @count < @pagesize
BEGIN
    FETCH NEXT FROM cur_page;
    SET @count += 1;
END
CLOSE cur_page; DEALLOCATE cur_page;

優勢:避免大偏移量掃描,極大提升深分頁性能。

避坑指南

  • 性能警示:游標逐行處理,CPU/IO 開銷大,優先考慮集合操作
  • @@FETCH_STATUS 三態:0=正常、-1=越界、-2=行已刪除
  • 游標位置:OPEN 後指向首行 之前,首次 FETCH NEXT 才到第一行
  • 及時 DEALLOCATE:釋放鎖與記憶體,防洩漏
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved