歷史數據從 SQL Server 2000 遷移至 2008,導入工具報錯:
OLE DB 訪問接口 'STREAM' 返回了對列 '[!BulkInsert].***' 無效的數據
根因:早期導入數據時,字符串末尾漢字被截斷,存入「半個漢字」(雙字節字符僅存高位字節)。SQL 2000 寬容處理(僅顯示異常),SQL 2008 嚴格校驗拒絕導入。
經協商,領導同意「去掉最後半個漢字」——必須批量處理,不可逐表寫程序。
-- 針對 varchar 字段,移除最後一個字節(若為半個漢字的高位字節)
UPDATE TargetTable
SET ProblemColumn = SUBSTRING(ProblemColumn, 1, DATALENGTH(ProblemColumn) - 1)
WHERE DATALENGTH(ProblemColumn) > 0
AND SUBSTRING(ProblemColumn, DATALENGTH(ProblemColumn), 1) BETWEEN 0x80 AND 0xFF; -- 簡易判斷高位字節
若字段較多,可動態生成腳本:
SELECT 'UPDATE ' + TABLE_NAME + ' SET ' + COLUMN_NAME +
' = SUBSTRING(' + COLUMN_NAME + ', 1, DATALENGTH(' + COLUMN_NAME + ') - 1) ' +
'WHERE DATALENGTH(' + COLUMN_NAME + ') > 0 ' +
'AND SUBSTRING(' + COLUMN_NAME + ', DATALENGTH(' + COLUMN_NAME + '), 1) BETWEEN 0x80 AND 0xFF;'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE IN ('varchar', 'char')
AND TABLE_NAME IN ('報錯表1', '報錯表2', ...);
SELECT * FROM Table WHERE COLUMN LIKE '%[^ -~]%' 抽樣檢查是否仍有亂碼nvarchar,問題通常不存在(Unicode 存儲完整雙字節)歷史數據遷移最怕「不見不散」的髒數據。導入前先用 SQL 2000 工具跑一遍試導入,收集所有報錯表/字段,批量生成清洗腳本,一次性修復,比逐表調試節省 90% 時間。