UPDATE TableA SET Col1 = Val1, Col2 = Val2 WHERE Condition;
UPDATE TableB
SET (Col1, Col2, Col3) = (SELECT Val1, Val2, Val3 FROM TableA WHERE TableA.Id = TableB.Id)
WHERE EXISTS (SELECT 1 FROM TableA WHERE TableA.Id = TableB.Id);
⚠️ SQL Server 不支持此語法,會報錯。
-- 隱式連接 (舊風格)
UPDATE B SET B.ClientName = A.Name FROM TableA A, TableB B WHERE A.Id = B.Id;
-- 顯式 JOIN (推薦,可 LEFT/RIGHT/INNER)
UPDATE B
SET B.ClientName = A.Name
FROM TableB B
LEFT JOIN TableA A ON A.Id = B.Id;
-- 多表更新同步
UPDATE A
SET A.Col1 = B.Col1, A.Col2 = B.Col2
FROM TableA A
INNER JOIN TableB B ON A.Id = B.Id
WHERE A.Status = 1;
優勢:單次掃描源表,避免 WHERE 和 SET 子查詢各掃描一次,性能顯著優於子查詢寫法。
UPDATE TableB
SET (Col1, Col2) = (SELECT Val1, Val2 FROM TableA WHERE TableA.Id = TableB.Id)
WHERE Id IN (SELECT Id FROM TableA WHERE TableA.Id = TableB.Id);
UPDATE LocalDB.dbo.TableB
SET Col1 = Remote.Col1
FROM LocalDB.dbo.TableB B
INNER JOIN [LinkedSvr].RemoteDB.dbo.TableA A ON A.Id = B.Id;
DELETE B FROM TableB B
LEFT JOIN TableA A ON A.Id = B.Id
WHERE A.Id IS NULL; -- 刪除 B 中無對應 A 的行
| 場景 | 推薦寫法 | 避坑提示 |
|---|---|---|
| SQL Server 單表關聯更新 | UPDATE ... FROM ... JOIN | 別用子查詢 SET,雙掃描慢 |
| Oracle/PostgreSQL 集合賦值 | SET (c1,c2) = (SELECT ...) | 需 WHERE EXISTS 防 NULL 覆蓋 |
| 大批量更新 | 分批次 (TOP 5000) 循環 | 避免長事務、鎖升級、日志暴漲 |
| 需回滾保障 | 顯式事務包裹 | 隱式事務單語句自動提交 |