| 特性 | 表值型別 (TVT) | 表變數 (@table) |
|---|---|---|
| 定義位置 | 資料庫層級 (CREATE TYPE) | 批次/SP 內部 (DECLARE) |
| 可重用性 | ✅ 多 SP/批次共用 | ❌ 僅當前作用域 |
| 參數傳遞 | ✅ SP 輸入參數 (READONLY) | ❌ 不可作參數 |
| 索引支援 | ✅ 可定義 PK/UNIQUE/非叢集 | ⚠ 僅隱含 PK/UNIQUE |
| 統計資訊 | ✅ 永久統計 | ❌ 無統計 (估計 1 行) |
| 並行計畫 | ✅ 支援 | ❌ 串行 |
| 版本需求 | SQL Server 2008+ | SQL Server 2000+ |
| 生命週期 | 物件永久存在 | 批次結束自動銷毀 |
-- 1. 建立型別 (資料庫層級,一次建立永久使用)
CREATE TYPE dbo.SubCardTable AS TABLE (
SC_ID VARCHAR(50),
ZhuKaInfo_ID VARCHAR(50),
Project_KeyName VARCHAR(50),
SC_CardNumber VARCHAR(50),
Statues INT DEFAULT 0,
SC_AddTime DATETIME,
SC_AddPerson VARCHAR(50),
SC_Money INT,
MainCardReceiveIntegral INT DEFAULT 0,
SC_RelationCustom VARCHAR(50),
SC_UseTime DATETIME,
PRIMARY KEY (SC_ID) -- 可定義索引
);
GO
-- 2. SP 使用
CREATE PROC usp_BatchInsertSubCard @Data dbo.SubCardTable READONLY
AS
INSERT INTO SubCard (SC_ID, ZhuKaInfo_ID, ...)
SELECT SC_ID, ZhuKaInfo_ID, ... FROM @Data;
GO
-- 3. C# 調用
var dt = new DataTable(); dt.Columns.Add(...); dt.Rows.Add(...);
var cmd = new SqlCommand("usp_BatchInsertSubCard", conn) { CommandType = CommandType.StoredProcedure };
var p = cmd.Parameters.AddWithValue("@Data", dt);
p.SqlDbType = SqlDbType.Structured;
p.TypeName = "dbo.SubCardTable";
cmd.ExecuteNonQuery();
DECLARE @mtTable TABLE (
Id INT PRIMARY KEY, -- 隱含叢集索引
Name VARCHAR(10)
);
INSERT INTO @mtTable VALUES (1, 'A'), (2, 'B');
SELECT * FROM @mtTable WHERE Id = 1;
適用:< 1 萬行、無需統計資訊、臨時中繼結果、SQL 2000/2005 相容。
#temp table (有統計、可建索引、支援並行)需要跨 SP/批次共用結構? → 是 → TVT 需要作 SP 參數批量傳入? → 是 → TVT 資料量 > 1 萬且需最優計畫? → 是 → #temp table 或 TVT(帶索引) 單批次內臨時小資料? → 是 → 表變數 SQL Server 2005 或更舊? → 是 → 表變數 或 #temp table