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

SQL Server 游標全面解析:從基礎到實戰範例

     編輯:關於SqlServer

什麼是游標?

游標讓你能逐列處理結果集,適用於必須依序、逐筆執行邏輯的情境 (如呼叫外部 API、複雜條件判斷)。但集合導向 (Set-based) 寫法通常效能更好,能用單一 SQL 解決時優先避免游標。

游標生命週期


DECLARE cursor_name CURSOR [LOCAL | GLOBAL]
    [FORWARD_ONLY | SCROLL]
    [STATIC | KEYSET | DYNAMIC | FAST_FORWARD]
    [READ_ONLY | SCROLL_LOCKS | OPTIMISTIC]
    FOR select_statement;

OPEN cursor_name;
FETCH NEXT FROM cursor_name INTO @var1, @var2, ...;
WHILE @@FETCH_STATUS = 0
BEGIN
    -- 處理邏輯
    FETCH NEXT FROM cursor_name INTO @var1, @var2, ...;
END
CLOSE cursor_name;
DEALLOCATE cursor_name;

實戰範例:加薪計算

情境:OriginSalary (原薪資) + AddSalary (調薪) → 更新回 OriginSalary。

集合導向寫法 (推薦)


UPDATE o
SET o.O_Salary = o.O_Salary + a.A_Salary
FROM OriginSalary o
JOIN AddSalary a ON o.O_ID = a.O_ID;

游標寫法 (教學用)


DECLARE @empId NVARCHAR(20), @addSal FLOAT;

DECLARE cur CURSOR LOCAL FAST_FORWARD READ_ONLY FOR
    SELECT O_ID, A_Salary FROM AddSalary;

OPEN cur;
FETCH NEXT FROM cur INTO @empId, @addSal;
WHILE @@FETCH_STATUS = 0
BEGIN
    UPDATE OriginSalary
    SET O_Salary = O_Salary + @addSal
    WHERE O_ID = @empId;
    FETCH NEXT FROM cur INTO @empId, @addSal;
END
CLOSE cur;
DEALLOCATE cur;

游標類型選擇指南

類型特性適用場景
FAST_FORWARD唯前向、唯讀、最佳效能單向掃描、不需更新
STATIC結果集快照、不反映後續異動需固定資料集、可捲動
KEYSET鍵值固定、非鍵值異動可見需捲動且反映資料變更
DYNAMIC完全反映所有異動、成本最高極少見,真正需要即時性

效能與替代方案

  • 游標在 TempDB 建立工作表,大量資料極慢。
  • 優先考慮:UPDATE ... JOIN、MERGE、CROSS APPLY、窗函數、Table-Valued Parameter。
  • 必須用游標時:加 LOCAL FAST_FORWARD READ_ONLY、盡早 DEALLOCATE。

常見錯誤

  • 忘記 DEALLOCATE 導致記憶體洩漏。
  • 在游標迴圈內執行 COMMIT 導致游標失效 (隱含 CLOSE)。
  • 使用 GLOBAL 游標污染連線池。

掌握游標原理,但請讓「集合思維」成為預設選擇。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved