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

SQL 以集合式寫法取代游標:單陳述式 UPDATE 範例

     編輯:關於SqlServer

前言

游標(Cursor)屬逐列處理,效能差、鎖定久、程式碼冗長。現代 SQL 最佳實務強調集合式思維,以單一陳述式完成批次更新。本文展示一個典型「依條件對應更新」的游標改寫範例。

原始游標邏輯(假設)

  1. 逐列讀取 Tb_Garden1。
  2. 對每列,去 Zyq.Tb_User 找 REPLACE(Name, '區', '') = Garden.Name 的第一筆 Id。
  3. 將找到的 Id 寫回 Tb_Garden1.Steward。

集合式改寫

UPDATE G
SET Steward = (
    SELECT TOP 1 U.Id
    FROM Zyq.Tb_User U
    WHERE REPLACE(U.Name, '區', '') = G.Name
)
FROM Tb_Garden1 G
WHERE EXISTS (
    SELECT 1
    FROM Zyq.Tb_User U
    WHERE REPLACE(U.Name, '區', '') = G.Name
);

關鍵點解析

技巧說明
子查詢回傳單值SELECT TOP 1 ... 確保標量子查詢不會因多筆結果報錯。
WHERE EXISTS 過濾僅更新有對應資料的列,避免將無對應列設為 NULL。
別名 G/U簡化多表參考,提升可讀性。
無游標宣告/開啟/擷取/關閉單一陳述式,最佳化器可產生平行計劃、批次鎖定,效能指數級提升。

效能對比(經驗值)

  • 10 萬列資料:游標約 45 秒 → 集合式約 0.8 秒。
  • 鎖定持續時間:游標逐列鎖定 → 集合式單一交易鎖定,阻塞大幅降低。
  • 記憶體:游標需維護遊標結構 → 集合式僅需查詢工作空間。

適用場景檢核

只要符合以下特徵,皆可嘗試改寫:

  • 逐列讀取來源表 → 查詢目標表 → 更新來源表同一列。
  • 邏輯可表達為「來源表每列對應目標表 0 或 1 列」。
  • 無複雜程序性控制流(如動態 SQL、外部 API 呼叫)。

進階替代方案

  • MERGE 陳述式:需同步 INSERT/UPDATE/DELETE 時。
  • CTE + ROW_NUMBER():目標表有多筆符合條件,需依規則取第一筆。
  • Table-Valued Parameter (TVP):應用層批次傳入資料集合。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved