| 型別 | 最大容量 | 相容性 | 適用場景 |
| `VARCHAR(MAX)` | 2 GB (2^31-1 位元組) | **完整支援所有字串函數**、可宣告變數、可作參數 | 大型文本、JSON、XML、日誌 |
| `NVARCHAR(MAX)` | 1 GB 字元 (2 GB 位元組) | 同 VARCHAR(MAX),Unicode | 多語言大文本 |
| `VARBINARY(MAX)` | 2 GB | 支援二進位操作函數 | 檔案流、圖片、加密資料 |
變數與參數使用
DECLARE @BigStr VARCHAR(MAX) = REPLICATE(CONVERT(VARCHAR(MAX), 'A'), 100000);
SELECT LEN(@BigStr); -- 100000,正確
SELECT REPLACE(@BigStr, 'A', 'B'); -- 完整支援
隱性陷阱:字串字面值預設為 VARCHAR(8000)
-- 錯誤示範
DECLARE @s1 VARCHAR(4001) = REPLICATE('A', 4001);
DECLARE @s2 VARCHAR(4001) = REPLICATE('A', 4001);
SELECT LEN(@s1 + @s2); -- 8000 (截斷!因兩者皆非 MAX,結果型別推斷為 VARCHAR(8000))
-- 正確做法:至少一邊為 MAX
SELECT LEN(CONVERT(VARCHAR(MAX), @s1) + @s2); -- 8002
SELECT LEN(REPLICATE(CONVERT(VARCHAR(MAX), 'A'), 8002)); -- 8002
**鐵律**:任何可能超過 8000 位元組的字串運算,**字面值必須顯式 `CONVERT(VARCHAR(MAX), ...)` 或變數宣告為 MAX**。
資料表欄位與儲存行為
- 建表:`CREATE TABLE T (BigCol VARCHAR(MAX));`
- **行溢出機制 (預設)**:
- 資料 + 其他欄位 ≤ 8060 位元組 → **行內儲存** (效能最佳)。
- 超過 8060 → **行外儲存** (LOB 頁面),行內留 24 位元組指標。
- 混合策略:小資料行內、大資料行外,平衡效能與空間。
- **強制行外 (如 TEXT/IMAGE)**:
`EXEC sp_tableoption 'T', 'large value types out of row', '1';`
反模式警示:濫用 MAX 型別
-- 糟糕設計
CREATE TABLE Address (
Name VARCHAR(MAX),
AddressLine1 VARCHAR(MAX),
City VARCHAR(MAX),
State VARCHAR(MAX),
PostalCode VARCHAR(MAX)
);
危害:
- **資料完整性喪失**:無長度約束,髒資料風險大增。
- **UI 設計困境**:輸入框寬度、驗證規則無依據。
- **優化器失效**:無法估算資料大小、選擇率,產生劣質計畫。
- **行溢出頻率增加**:預期行大小膨脹,更多行外存取。
**原則**:**業務實際最大長度 + 適度緩衝** 定義 `VARCHAR(n)`,僅真正不可預估大小 (如文本、JSON、日誌) 才用 MAX。
相容性與遷移建議
- 舊 `TEXT`/`NTEXT`/`IMAGE` 欄位 → `ALTER TABLE ALTER COLUMN Col VARCHAR(MAX)` (元資料操作、瞬間完成、無資料移動)。
- 應用層代碼無需修改 (ADO.NET/SQL Client 自動對應 `SqlDbType.VarChar`/`-1`)。
- SSIS/BCP/複寫/鏡像/AlwaysOn 完整支援。
結語
MAX 型別是 SQL Server 2005 **最實用、影響面最廣** 的功能之一:徹底解決大物件資料「二等公民」地位,**讓大字串享有與小字串同等的函數支援、變數宣告、參數傳遞、優化器統計**。善用之:真正大物件用 MAX、業務有界用 `VARCHAR(n)`、字面值超 8K 必轉 MAX、拒絕濫用。遷移 TEXT 到 MAX,一勞永逸。
- 上一篇文章: SQL Server Min/Max Server Memory 實戰配置:讓資料庫與多應用程式和諧共存
- 下一篇文章: SQL Server 附加資料庫錯誤 1813 解決方案:遺失 LDF 檔案的標準急救流程
Copyright ©
程式碼之家 All Rights Reserved