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

SQL Server 游標從入門到實戰:概念、語法、分步示例與薪資加薪業務完整演示

     編輯:關於SqlServer

什麼是游標

游標是結果集的指針,允許逐行處理查詢返回的數據,將集合操作轉化為行級迭代。適用於:必須逐行邏輯、動態 SQL 構建、跨表複雜業務無法集合化時。

游標生命週期 5 步驟

  1. 聲明:DECLARE cursor_name CURSOR [LOCAL | GLOBAL] [FORWARD_ONLY | SCROLL] [STATIC | KEYSET | DYNAMIC | FAST_FORWARD] FOR select_statement;
  2. 打開:OPEN cursor_name; —— 執行查詢、構建結果集、指針指向第一行之前。
  3. 讀取:FETCH [NEXT | PRIOR | FIRST | LAST | ABSOLUTE n | RELATIVE n] FROM cursor_name INTO @var1, @var2, ...;
  4. 關閉:CLOSE cursor_name; —— 釋放結果集、保留定義。
  5. 釋放:DEALLOCATE cursor_name; —— 釋放定義、內存資源。

游標選項關鍵差異

選項行為適用場景
FAST_FORWARD只進、只讀、優化開銷最小單向遍歷、不更新、性能最優
STATIC複製數據到 tempdb,快照隔離需穩定結果集、允許併發修改基表
DYNAMIC實時反映基表變更需看到最新數據、開銷最大
KEYSET鍵集固定,非鍵列變更可見折中方案
SCROLL支持 FIRST/LAST/PRIOR/ABSOLUTE需隨機跳轉

實戰案例:薪資表 + 加薪表 → 更新薪資

表結構

CREATE TABLE OriginSalary (O_ID NVARCHAR(20) PK, O_Name NVARCHAR(50), O_Salary FLOAT);
CREATE TABLE AddSalary (O_ID NVARCHAR(20) PK, A_Salary FLOAT);
INSERT INTO OriginSalary VALUES ('E01','張三',5000),('E02','李四',6000),('E03','王五',7000);
INSERT INTO AddSalary VALUES ('E01',500),('E02',300),('E03',200);

游標存儲過程實現

CREATE PROCEDURE usp_ApplySalaryRaise
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @EmpID NVARCHAR(20), @Raise FLOAT;

    -- 1. 聲明游標(只進、只讀、高性能)
    DECLARE cur_raise CURSOR FAST_FORWARD FOR
        SELECT O_ID, A_Salary FROM AddSalary;

    -- 2. 打開
    OPEN cur_raise;

    -- 3. 讀取第一行
    FETCH NEXT FROM cur_raise INTO @EmpID, @Raise;

    -- 4. 循環處理
    WHILE @@FETCH_STATUS = 0
    BEGIN
        UPDATE OriginSalary
        SET O_Salary = O_Salary + @Raise
        WHERE O_ID = @EmpID;

        FETCH NEXT FROM cur_raise INTO @EmpID, @Raise;
    END

    -- 5. 關閉與釋放
    CLOSE cur_raise;
    DEALLOCATE cur_raise;
END;

執行驗證

EXEC usp_ApplySalaryRaise;
SELECT * FROM OriginSalary;
/*
O_ID  O_Name  O_Salary
E01   張三    5500
E02   李四    6300
E03   王五    7200
*/

集合化替代方案(強烈推薦)

上述業務完全不需要游標,單條 UPDATE 即可:

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

優勢:單語句、原子性、並行執行計劃、無循環開銷、鎖持有時間極短。

游標性能警示與最佳實踐

  • ⚠️ 游標逐行處理,每行一次上下文切換、鎖獲取/釋放,性能比集合操作慢 10-100 倍。
  • ✅ 能用集合操作(JOIN/EXISTS/窗口函數)絕不寫游標。
  • ✅ 必須用游標時:
    ① 加 FAST_FORWARD / LOCAL 選項。
    ② FETCH NEXT INTO 變量列表 避免 SELECT *。
    ③ 循環內禁止複雜查詢/事務/等待。
    ④ 及時 CLOSE/DEALLOCATE。
  • 🔍 監控:sys.dm_exec_cursors 查看活動游標、cursor_threshold 配置閾值觸發異步填充。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved