2017-10-17 66 views
1

有一個奇怪的空白字符,我似乎無法擺脫那偶爾會出現在我的數據從Excel導入時。顯然,它會作爲空白字符出現,但SQL Server將其視爲問號(ASCII 63)。如何在SQL Server中刪除奇怪的Excel字符?

declare @temp nvarchar(255); set @temp = '[email protected]?am.com' 
select @temp 

回報:

[email protected]?am.com 

我怎樣才能擺脫空白的沒有擺脫真正的問號?如果我查看每個「?」的ASCII碼當我獲得63個角色時,其中只有一個角色是真正的問題標記。

+0

如果您執行Ltrim(@temp)會怎麼樣? – Harry

+2

注意:如果出於某種原因想要保持字符串不變,您應該設置@temp = N'mystring'(顯式聲明該字符串是unicode,即使您的變量是NVARCHAR,也應該這樣做')而不是你目前正在做的事情。 – ZLK

+0

看起來像一個字符集不匹配。 – Namphibian

回答

2

查看this answer有類似問題的人。對不起,如果這是一個長長的囉嗦:

SQL Server似乎通過映射不可代表的字符(沒有合適的替代字符)到問號來將Unicode變爲ASCII。要複製它,請嘗試打開Character Map Windows程序(應該安裝在大多數機器上),選擇Arial作爲字體並找到U + 034f「組合Grapheme連接器」。選擇這個角色,複製到剪貼板,然後粘貼下面的單引號之間:

declare @t nvarchar(10) 
set @t = '͏' 
select rtrim(ltrim(@t)) -- we can try and trim it, but by this stage it's already a '?' 

你會得到一個問號了,因爲它不知道如何當它施放它代表了這個非ASCII字符到varchar。爲了強制它接受它爲雙字節字符(nvarchar),您需要改爲使用N'',如前所述。上述引號前添加N問號消失(但原來不可見字符在輸出保存 - 和ltrim,並如下面所示rtrim將無法​​將其刪除):

declare @t nvarchar(10), 
     @s varchar(10) -- note: single-byte string 
set @t = rtrim(ltrim(N'͏')) -- trimming doesn't work here either 
set @s = @t 
select @s -- still outputs a question mark 

進口數據絕對可以做到這個,我以前見過,像上面顯示的那些人物特別難以診斷,因爲你看不到他們!您需要創建某種清理流程來刪除這些不打印郵件(以及其他任何垃圾郵件),並確保您在任何地方都使用nvarchar,否則最終會出現此問題。更糟的是,那些虛幻的問號將成爲真正的問號,你將無法與合法問號區分開來。

要查看字符代碼你處理,你可以投爲varbinary如下:

declare @t nvarchar(10) 
set @t = N'͏test?' 
select cast(@t as varbinary) -- returns 0x4F0374006500730074003F00 

-- Returns: 
-- 0x4F03 7400 6500 7300 7400 3F00 
-- badchar t e s t ? 

我們擺脫它:

declare @t nvarchar(10) 
set @t = N'͏test?' 
select cast(@t as varbinary) -- bad char 
set @t = replace(@t COLLATE Latin1_General_100_BIN2, nchar(0x034f), N''); 
select cast(@t as varbinary) -- gone! 

注意,我不得不調換字節順序從0x4f030x034f(同樣的原因「t」在輸出中出現爲0x7400,而不是0x0074)。有關我們使用二進制排序規則的一些說明,請參閱this answer

這是一種混亂,因爲你不知道什麼是骯髒的人物,他們可能是成千上萬的可能性之一。一種選擇是使用like甚至unicode()function迭代字符串,並放棄不在可接受字符列表中的字符串中的字符,但這可能會很慢。這可能是因爲你的大部分壞字符都在字符串的開始或結尾,如果這是你認爲可以做出的假設,那麼這可能會加速這個過程。

根據我上面向您展示的內容,如果您需要導入大量數據,您可能需要在SQL Server外部或作爲SSIS導入的一部分構建其他進程。如果您不確定這是否是最好的方法,那麼最好在一個新問題中回答。

我希望有幫助。

+0

很好的解釋!從字面上看,它正在瘋狂。在我的情況下,字符是「0x0B20」... unicode爲零寬度空間。這意味着WTF,我不知道。 – wgpubs