MegaWare專案中,市場部文檔超過8000位元組,只能用TEXT。但REPLACE、CHARINDEX、SUBSTRING等字串函數不支援TEXT/IMAGE(超過8KB更不行),連區域變數宣告都不支援。更新文檔頁腳需用晦澀的READTEXT/WRITETEXT,開發維護極度痛苦。
VARCHAR(MAX)、NVARCHAR(MAX)、VARBINARY(MAX):
REPLACE、SUBSTRING、LEN等)。DECLARE @BigString VARCHAR(MAX)DECLARE @S1 VARCHAR(4001), @S2 VARCHAR(4001)
SET @S1 = REPLICATE('1',4001); SET @S2 = REPLICATE('2',4001)
SELECT LEN(@S1 + @S2) -- 8000(截斷),非8002
-- 修正:任一宣告為MAX或轉換
SELECT LEN(CONVERT(VARCHAR(MAX), @S1) + @S2) -- 8002
SELECT LEN(REPLICATE('1', 8002)) -- 8000
SELECT LEN(REPLICATE(CONVERT(VARCHAR(MAX), '1'), 8002)) -- 8002
| 類型 | 行溢出行為 |
|---|---|
| TEXT/IMAGE | 永遠行外存儲,列留16位元組指標 |
| MAX(預設) | 資料+其他欄位<8060位元組 → 行內;超過 → 行外 |
MAX(啟用large value types out of row) | 行為同TEXT/IMAGE,強制行外 |
EXEC sp_tableoption 'BigStrings', 'large value types out of row', '1'
-- 反面教材:所有欄位用MAX
CREATE TABLE Addresses (
Name VARCHAR(MAX), AddressLine1 VARCHAR(MAX), ...
)
缺點:資料完整性約束缺失(無長度限制)、UI設計無依據、查詢優化器無統計資訊(無法估算行大小、選擇性),導致執行計畫劣化。原則:業務實際需要多大,給多大;僅在真正需要>8000位元組時用MAX。
Steve(DBA)原需整夜研究READTEXT/WRITETEXT更新頁腳,升級2005後一行REPLACE搞定。TEXT/IMAGE成為不愉快回憶。