T-SQL 資料操作語言 (DML) 核心三大指令全解析
掌握 INSERT、UPDATE、DELETE 的完整語法、行為細節與最佳實務,是資料庫開發者的基本功。本文系統整理語法選項、隱性行為 (DEFAULT/IDENTITY/NULL)、錯誤處理與效能考量。
一、INSERT — 插入新資料列
完整語法結構
INSERT [INTO] {table_name | view_name}
[ ( column_list ) ]
{
VALUES ( { DEFAULT | expression } [ ,...n ] )
| DEFAULT VALUES
| select_statement
| execute_statement
}
四種插入模式詳解
| 模式 | 語法範例 | 適用場景 | 關鍵行為 |
| 值清單 | INSERT T VALUES (1, 'A', GETDATE()) | 單筆/少量手工插入 | 須符合定義順序;未指定欄位走 DEFAULT/NULL/IDENTITY |
| 欄位清單 + 值 | INSERT T (ColB, ColA) VALUES ('A', 1) | 部分欄位插入、調整順序 | 未列欄位同值清單規則 |
| SELECT 來源 | INSERT T (A,B) SELECT ColX, ColY FROM S WHERE... | 大量資料搬移、ETL | 結果集欄位數/型別/順序必須完全對應 |
| EXEC 來源 | INSERT T EXEC usp_GetData | 預存程序/動態 SQL 回傳結果集 | SP 需 SET NOCOUNT ON 避免干擾 |
隱性欄位處理規則 (未在 column_list 中)
IDENTITY / timestamp:引擎自動產生
- 有
DEFAULT 约束:使用預設值
- 允許
NULL:寫入 NULL
- 無預設且
NOT NULL:報錯,整批回滾
效能與最佳實務
- 大量匯入:
BULK INSERT / bcp / SqlBulkCopy (最小記錄、鎖表、需權限)
- 最小記錄插入:
INSERT INTO T WITH (TABLOCK) SELECT ... (簡單/大量記錄模式)
- 避免單筆迴圈:應用層打包批次 (如 1000 筆/批) 或使用表值參數 (TVP)
二、UPDATE — 修改現有資料
核心語法 (常用簡化版)
UPDATE table_name
SET col1 = expr1, col2 = expr2, ...
[FROM table_source]
[WHERE search_condition];
關鍵行為與陷阱
三、DELETE / TRUNCATE TABLE — 刪除資料
DELETE
DELETE [FROM] table_name [WHERE condition];
- 逐列記錄記錄檔,可
ROLLBACK,觸發 AFTER DELETE Trigger
- 支援
FROM 多表關聯刪除 (同 UPDATE)
- 不重置
IDENTITY 種子
TRUNCATE TABLE
TRUNCATE TABLE table_name;
- 釋放資料頁 (最小記錄),不可回滾 (隱含交易)
- 重置
IDENTITY 至種子值
- 不觸發 Trigger
- 限制:被外鍵參考、參與索引檢視、異構複寫發佈時不可用
選擇決策表
| 需求 | 指令 |
| 刪除特定條件資料,需回滾/觸發 Trigger | DELETE |
| 清空整表,極速、重置 IDENTITY、無外鍵依賴 | TRUNCATE TABLE |
| 清空整表,但保留 IDENTITY / 有外鍵 / 需 Trigger | DELETE (無 WHERE) + DBCC CHECKIDENT RESEED |
實戰範例:UserTable 完整操作示範
-- 建表
CREATE TABLE UserTable (
UserID INT IDENTITY(1,1) PRIMARY KEY,
UserName NVARCHAR(20) NOT NULL,
Gender NCHAR(2) DEFAULT N'未填',
Age TINYINT NULL,
RegDate DATETIME DEFAULT GETDATE()
);
-- 1. 插入 (多種方式)
INSERT UserTable (UserName, Age) VALUES (N'張三', 25); -- 指定欄位
INSERT UserTable VALUES (N'李四', N'男', 30, DEFAULT); -- 全欄位含 DEFAULT
DECLARE @Name NVARCHAR(20) = N'王五';
INSERT UserTable (UserName, Gender, Age) VALUES (@Name, N'女', 28); -- 變數
-- 2. 修改
UPDATE UserTable SET Gender = N'男' WHERE Gender IS NULL; -- 批次修正
UPDATE UserTable SET Age = Age + 1 WHERE UserID = 1; -- 運算式更新
-- 3. 刪除
DELETE UserTable WHERE UserName = N'張三';
TRUNCATE TABLE UserTable; -- 快速清空測試資料
總結:DML 鐵律
- 永遠在
WHERE 先用 SELECT 驗證影響範圍
- 大量操作分批、最小記錄、監控記錄檔
- 善用
DEFAULT、IDENTITY、ROWVERSION 讓引擎分擔責任
- 刪除前確認外鍵、Trigger、複寫相依性