SSMS匯出指令碼以UTF16LE編碼問題
前文說到,最近在進行一些SQL Server資料庫轉移工作,而有些資料庫是以SQL script方式進行移轉,其中有些資料庫因資料量巨大,匯出的SQL script奇大無比,高達數十GB。在第一次轉移時,使用sqlcmd發生不明原因導致作業中斷,懷疑是SQL script太大導致,因此打算進行檔案切割。
Windows環境裡,不若Linux或MacOS,有方便的工具指令如split可以切割檔案,所幸Git安裝時順帶了一套MinGW Bash環境,便在此環境進行切割。
以3,000,000行為單位進行切割:
split -l 3000000 scripts.sql
為了確保切割過的每一個檔都能正常插入資料,寫了bash shell script幫每個檔的頭和尾各補了USE [xxx]; 、SET IDENTITY_INSERT ON; 以及 SET IDENTITY_INSERT OFF; ,當然還有很多GO。
沒想到一餵給sqlcmd跑就掛了,出師不利 XD
搞了一套能開大檔的文字編輯器emedtior,一揭開這秘密不得了!大変だ!把問題盤點下來:
- SQL Server產生指令碼預設以UTF16LE格式編碼
- MinGW bash指令預設以UTF8編碼處理檔案
- split一遇到 newline 就切下去,把本來該被當成同一個字元的下一個位元組 0x00 留給下一個檔,這讓第1個檔以外的其他檔案實際上變成了UTF16BE編碼(囧)
- bash shell script補上的header、footer讓檔案成了一個UTF16LE、UTF8混合的四不像
後來怎麼處理呢?用了笨方法,先轉成UTF8吧:
iconv -f UTF-16LE -t UTF-8 scripts.sql