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

SQL Server 游標完全指南:類型、生命週期、聲明與操作實戰詳解

     編輯:關於SqlServer

游標是逐行處理結果集的機制,提供在結果集中前後導航、定位特定行、對當前行執行更新/刪除的能力。本文系統梳理游標組成、分類、生命週期、語法與實戰範例。

一、游標的兩大核心組成

  • 游標結果集:定義游標的 SELECT 語句返回的行集合。
  • 游標位置:指向結果集中某一行的當前指標。

二、三大類游標架構

類別運行位置典型應用場景
API 伺服器游標伺服器端客戶端應用透過 ODBC/OLE DB/ADO 調用 API 函數操作
T-SQL 游標伺服器端存儲過程、觸發器、批次腳本中使用 DECLARE CURSOR
API 客戶端游標客戶端將整個結果集緩存至客戶端,僅支援靜態與只進游標

API 伺服器游標四種模式

  • 靜態游標:開啟時將結果集複製到 tempdb,唯讀,不反映後續任何資料變更,但能看到開啟後被刪除的行。
  • 動態游標:每次提取都反映結果集的所有變更(資料值、順序、成員資格),開銷最大。
  • 只進游標:僅支援 FETCH NEXT 順序讀取,不支援滾動,但反映所有變更。
  • 鍵集驅動游標:開啟時固定成員與順序(鍵值存 tempdb),非鍵值變更可見,新增行不可見(除非重開),折衷方案。

三、T-SQL 游標生命週期五階段

  1. 聲明:DECLARE cursor_name CURSOR [LOCAL|GLOBAL] [FORWARD_ONLY|SCROLL] [STATIC|KEYSET|DYNAMIC] [READ_ONLY|SCROLL_LOCKS|OPTIMISTIC] FOR select_statement
  2. 打開:OPEN cursor_name 執行 SELECT 填充結果集,位置指向第一行前。
  3. 提取:FETCH [NEXT|PRIOR|FIRST|LAST|ABSOLUTE n|RELATIVE n] FROM cursor_name INTO @var1, @var2... 逐行讀取至變數。
  4. 關閉:CLOSE cursor_name 釋放結果集鎖定,游標定義保留,可重新 OPEN。
  5. 釋放:DEALLOCATE cursor_name 徹底移除游標定義釋放資源。

四、常用屬性與參數詳解

  • 作用域:LOCAL(預設,批次/程序結束自動釋放)vs GLOBAL(會話級,斷開連接才釋放)。
  • 滾動性:FORWARD_ONLY(預設,僅 NEXT)vs SCROLL(任意方向)。
  • 並發控制:
    • READ_ONLY:唯讀,無鎖。
    • SCROLL_LOCKS:讀取時加鎖(悲觀),保證更新成功。
    • OPTIMISTIC:無鎖,更新時比對時間戳/校驗和,衝突則失敗(樂觀)。

五、完整實戰範例

DECLARE @GoodsCode CHAR(20), @GoodsName CHAR(20)
DECLARE MyCursor CURSOR SCROLL FOR
    SELECT GoodsCode, GoodsName FROM Master_Goods ORDER BY GoodsID

OPEN MyCursor
FETCH NEXT FROM MyCursor INTO @GoodsCode, @GoodsName

WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT @GoodsCode + ':' + @GoodsName
    FETCH NEXT FROM MyCursor INTO @GoodsCode, @GoodsName
END

CLOSE MyCursor
DEALLOCATE MyCursor

六、當前行更新/刪除語法

-- 更新當前行
UPDATE Master_Goods SET GoodsName = 'NewName' WHERE CURRENT OF MyCursor

-- 刪除當前行
DELETE FROM Master_Goods WHERE CURRENT OF MyCursor

七、效能與最佳實踐提醒

  • 游標屬 RBAR(Row-By-Agonizing-Row) 操作,效能遠低於集合操作(SET-based),能用單一 SQL 解決時盡量避免游標。
  • 必須使用時:優先選 LOCAL FORWARD_ONLY READ_ONLY(最輕量),避免 SCROLL_LOCKS 造成阻塞。
  • @@CURSOR_ROWS 返回最後開啟游標的行數(全域變數,僅對當前連接最後一次 OPEN 有效)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved