程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> 關於SQL的char,varchar字段在導出時切斷中文字符顯示問號或亂碼的問題

關於SQL的char,varchar字段在導出時切斷中文字符顯示問號或亂碼的問題

編輯:關於SqlServer

最近在處理客戶的FTP下來的資料,出現如題的問題

txt文本裡有如下記錄:

廣東省某某某某某某某某某公司-IC卡,100,100

廣東省某某某某某某某某公司-IC?100,100

問題,下面這行的分隔符不見了,造成數據無法導入本地SQL2000

這個字段類型是varchar(30),這是最近的文檔資料,但我發現導出的資料有超過30長度的。證明這個字段現在只是修改了文檔資料為30長度,而數據庫必然是大於30的,只是從其它工單表裡轉入資料時作了切斷來滿足現在文檔的要求,否則也不可能完整存放長度大於30的字符串(第一行)。

而這個切斷就出現了問題,其實我們看到的問號,並非是英文的問號,而是半個漢字與逗號的結合造成的亂碼。

所以總結一下就是:數據長度剛好30,而且英文字符的數量是奇數,並且以漢字結尾

當然,如果是以英文結束並切斷英文部分,是不會造成這個問題的;如果英文字符數量是偶數也沒問題。

徹底解決方法:

這個問題的澈底解決方法是不要作切斷,否則肯定會出現或多或少的問題。而至於要完整的切斷一個中文,在處理效率上不現實。當然這是程序的問題了。

折衷的解決方法:

1. 本地文本替換問號為逗號,但不一定保險。因為目前除問號問題外,還出現了數據折行顯示,甚至跳過幾行等問題,其歸根結底是中文切字造成不可見字符造成的。而且這個沒什麼規律。

因為我們雖然在notepad裡看到的是問號"?",並且可以替換,但是編程來替換就不行,因為末字符是ascii>127的,而且你無法判斷是半個字符,因為漢字就是兩個半個字符組合而成,除非用我上面用黑體顯示的那個規律來判斷之。(與notepad裡能看到問號是兩碼事)

2. 本地表加寬成varchar(40),導出是增加一個“A-Z”的字符,如果後面有半個字符則結合成一個字或者問號,從而不會與逗號結合。如果沒有半個字符則顯示出這個英文,影響也不大。

導出時選擇用一條sql語句來篩選:select id,name=name+'A',price from tab_name where 1=1

我在sql2000裡測試增加一個'A':IP專?3269334變成了: IP專蟌,3269334

如果末尾加英文的空格,顯然比較貼切,有半個字符的顯示為問號,但不吃掉逗號,而正常的記錄只是多一個空格出來,完全不影響實際上使用。(推薦)

select id,name=name+' ',price from tab_name where 1=1

IP專?3269334 變成了: IP專?,3269334

然聰明的人能想到,先在末尾添加一個字符,再用left(name,len(name)-1)來處理也是可以的,因為left是基於一個完整的字符,英文算一個,漢字也算一個。

select id,name=left(name+'A ',len(name+'A')-1),price from tab_name where 1=1

(結果非常完美)

當然還有人認為不用添加一個字符,直接切掉末尾字符,當然沒問題的字段也會被切掉一個,當然不可以。

3. 判斷長度為30而且英文字符數為奇數,則切斷末尾的半個漢字。這個方法太費勁。而且這種方法不是數據庫維護人員能做到的。(簡直沒必要費這個勁)

4. 在導出時用sql語句把字段轉換成nvarchar(30),我在sql2000裡測試ok.

select id,name=cast(name  as nvarchar(30)),price from tab_name where 1=1

即說2,4的方法是可行的。windowxp+sql2000裡我測試過。其它DBsys和OS未作測試。 



  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved