處理客戶 FTP 下載的文字檔資料時,發現 varchar(30) 欄位匯出資料出現詭異問號:
正常:廣東省某某公司-IC卡,100,100
異常:廣東省某某公司-IC?,100,100 ← 分隔符逗號被「吃掉」
經深入分析,問題觸發條件為三個條件同時滿足:
因中文字元佔 2 個位元組,英文佔 1 個。當英文為奇數時,最後一個中文字元會被「切一半」,剩下的半個位元組與後續分隔符(逗號)組合成不可見字元,在記事本顯示為問號,實際上是亂碼。
不截斷資料。截斷中文必然導致位元組對齊問題,處理效率也低。應在資料庫層面確保欄位長度足夠,或由應用程式驗證長度。
SELECT id, name = name + ' ', price FROM tab_name WHERE 1=1
原理:補上空格後,若原本有半個中文字元,會與空格組合成完整字元或問號,不會吃掉分隔符;正常資料只是多一個空格,不影響使用。
SELECT id, name = LEFT(name + 'A ', LEN(name + 'A') - 1), price FROM tab_name WHERE 1=1
原理:LEFT 以「字元」為單位計算長度(中英文各算 1),補上字元後再截回原長度,確保位元組對齊。
SELECT id, name = CAST(name AS NVARCHAR(30)), price FROM tab_name WHERE 1=1
在 SQL Server 2000 + Windows XP 環境測試通過。Unicode 儲存無位元組對齊問題。
-- 本地表擴大為 varchar(40)
SELECT id, name = name + 'A', price FROM tab_name WHERE 1=1
測試:IP專?3269334 → IP專蟌,3269334(半個字元與 A 組合成完整字,分隔符保留)。
匯出中文資料時,位元組對齊是關鍵。最佳實務是避免截斷;若必須處理既有截斷資料,補空格法(方案 1)最簡單有效,LEFT 函數法(方案 2)最完美,CAST NVARCHAR(方案 3)最標準。請根據環境與限制選擇適合方案。