昨晚預(yù)生產(chǎn),出了不少問題,其中SQL文件隱藏亂碼問題始料未及,這個(gè)幾年前就出現(xiàn)的問題,如今又重現(xiàn)。時(shí)間是最好的療傷神藥,同時(shí)也是“忘情水”,所以說好記性不如爛筆頭,記錄下來很重要,方便日后溫習(xí)。
平時(shí)都是用UE(UltraEdit)工具來打開或編寫SQL文件,而且文件都是用UTF-8編碼保存,所以亂碼看不到有任何亂碼問題。
但昨晚部署后看到執(zhí)行腳本后的日志(見下方),還是頗感意外。
Server 'XXXX', Line 1:
Incorrect syntax near '?'.
Msg 102, Level 15, State 1:
Server 'XXXX', Line 1:
Incorrect syntax near '?'.
一番冷靜之后,開始一遍遍檢查腳本,無果。復(fù)制到SqlDbx客戶端執(zhí)行,一點(diǎn)問題都沒。
后面把整個(gè)文件內(nèi)容拷貝到空白文本文件保存后再復(fù)制回去,還是不行。
最后同事說用SqlDbx客戶端打開就看到亂碼了,腫么可能?我剛才才試過。再三追問才知道,原來是打開文件的姿勢不對。她是直接把文件拖到客戶端打開,而我是復(fù)制到客戶端,就這點(diǎn)區(qū)別,囧。
自己試了一次,果不其然,首行就赫赫顯示了上面的幾個(gè)“特殊字符”。
后面又拖到eclipse,結(jié)果也可以看到。
考慮到文件全都是英文,并無中文,所以保存為ANSI/ASCII編碼便可解決亂碼問題。
????????????????????????????????????????????????????????????????????????????????????????????????——記錄于2018-11-06
下面趁這個(gè)機(jī)會普及下編碼知識吧。
ANSI和ASCII區(qū)別、Unicode和UTF-8區(qū)別
ANSI: American?National?Standards?Institute?的縮寫,?意思是美國國際標(biāo)準(zhǔn)學(xué)會,?ASCII方案就是他們制定的。
ASCII:? American Standard Code for Information Interchange.(美國信息交換標(biāo)準(zhǔn)碼)
ASCII碼中,一個(gè)英文字母占一個(gè)字節(jié)的空間,不分大小寫。
由于美帝國主義沒有想到其他落后國家需要用到計(jì)算機(jī),所以只使用256個(gè)字符(2的八次方)表示大小寫字母,數(shù)字和符號,并且剛好256個(gè)字符都用完了。?
到中國人使用計(jì)算機(jī)的時(shí)候,已經(jīng)沒有可用的字符狀態(tài)來表示漢字了。但這難不倒智慧的中國人民,我們將127號后面的奇異符號給取消,然后將兩個(gè)127號后的字符表示為一個(gè)漢字。這就是GB2312的來源,它是對 ASCII 的中文擴(kuò)展,后面由于字符還是不夠用,所以又產(chǎn)生了GBK,GB18030。
結(jié)果每個(gè)國家都跟中國一樣,搞出自己的一套編碼標(biāo)準(zhǔn),彼此之間互不兼容。簡直亂出一鍋粥。
最后 ISO(國際標(biāo)誰化組織) 出手了:廢除所有地區(qū)性編碼,采用兩個(gè)字節(jié)表示一個(gè)字符,也就是16位表示所有一切字符。缺點(diǎn)在于由于"半角"英文符號只需要用到低8位,所以其高 8位永遠(yuǎn)是0,因此這種大氣的方案在保存英文文本時(shí)會多浪費(fèi)一倍的空間。該方案史稱Unicode 。
UTF(UCS transfer format) 是隨著計(jì)算機(jī)網(wǎng)絡(luò)興起而出現(xiàn)的傳輸標(biāo)準(zhǔn)。UTF-8就是每次傳輸8個(gè)位數(shù)據(jù),UTF-16就是每次傳輸16個(gè)位數(shù)據(jù)。只不過UNICODE跟UTF不是一一對應(yīng)的關(guān)系,而是通過一些算法和轉(zhuǎn)換規(guī)則。
參考資料:
https://blog.csdn.net/zeroubuntu/article/details/19680005
https://blog.csdn.net/xiangxianghehe/article/details/77574965