將「表結構」定義為強型別,直接作為參數傳遞給預存程序/函數,享受:
PRIMARY KEY (col1))。MERGE、INSERT...SELECT 無縫整合。USE Test;
GO
-- 1. 建立使用者定義表類型
CREATE TYPE dbo.MyType AS TABLE
(
col1 INT NOT NULL,
col2 VARCHAR(20) NULL,
col3 DATETIME NULL,
PRIMARY KEY (col1) -- 支援索引與約束!
);
GO
-- 2. 使用 TVP 的預存程序
CREATE PROCEDURE usp_BatchUpsertProducts
@Products dbo.MyType READONLY -- 必須加 READONLY
AS
BEGIN
SET NOCOUNT ON;
-- 範例:UPSERT 邏輯
MERGE INTO dbo.Products AS Target
USING @Products AS Source
ON Target.ProductID = Source.col1
WHEN MATCHED THEN
UPDATE SET Name = Source.col2, ModifiedDate = Source.col3
WHEN NOT MATCHED THEN
INSERT (ProductID, Name, ModifiedDate)
VALUES (Source.col1, Source.col2, Source.col3);
END
GO
-- 3. 客戶端呼叫範例 (C#)
/*
DataTable tvp = new DataTable();
tvp.Columns.Add("col1", typeof(int));
tvp.Columns.Add("col2", typeof(string));
tvp.Columns.Add("col3", typeof(DateTime));
// 填充資料...
using (SqlCommand cmd = new SqlCommand("usp_BatchUpsertProducts", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
var param = cmd.Parameters.AddWithValue("@Products", tvp);
param.SqlDbType = SqlDbType.Structured;
param.TypeName = "dbo.MyType";
cmd.ExecuteNonQuery();
}
*/

CREATE TYPE dbo.IdList AS TABLE (Id INT PRIMARY KEY);
GO
CREATE PROCEDURE usp_BatchDelete @Ids dbo.IdList READONLY
AS
DELETE FROM TargetTable WHERE Id IN (SELECT Id FROM @Ids);
CREATE PROCEDURE usp_SyncOrderHeaderDetail
@Headers dbo.OrderHeaderType READONLY,
@Details dbo.OrderDetailType READONLY
AS
BEGIN
-- Header UPSERT
MERGE ... USING @Headers ...;
-- Detail UPSERT (FK 關聯 Header)
MERGE ... USING @Details ...;
END
將 TVP 資料直接 INSERT 至分割表的 Staging 分割區,再 SWITCH 進主分割區,實現極速載入。
| 方案 | 耗時 (秒) | CPU (ms) | Logical Reads | 備註 |
|---|---|---|---|---|
| TVP + MERGE | 12 | 8,500 | 120,000 | 最佳綜合效能 |
| XML + OPENXML | 45 | 32,000 | 480,000 | XML 解析佔 70% CPU |
| T-SQL Split + Loop | 180+ | 120,000 | 1,200,000 | RBAR 模式極慢 |
| CLR Split | 28 | 15,000 | 200,000 | 部署維護成本高 |
Type__Param )。MERGE 簡化 UPSERT。SqlDbType.Structured + DataTable/IEnumerable。TVP 是 SQL Server 2008 最具生產力提升的 T-SQL 特性之一。它將「表」作為一等公民參數,徹底消除批量傳遞的序列化/反序列化、字串拼接、動態 SQL 等反模式。配合 MERGE、分割表、Columnstore 索引,構建出高效、可維護、型別安全的資料搬運管線。