2016-12-12 78 views
3

這是純粹的理論問題來包裹我的腦袋超出排序規則的Unicode(UTF-16)數據如何存儲在varchar列中?

比方說我有Unicode cyclone(1F300)符號。如果我試圖將其存儲在具有默認Latin1_General_CI_AS整理varchar列,旋風符號不可不適合一個字節即每個符號用於varchar ...

的方法,我可以看到這個工作:

  1. 像JavaScript一樣使用基本平面符號(BMP),它將它們存儲爲2個符號(代理對),然後需要額外的處理以便put them back together ...
  2. 只需截斷符號,存儲第一個字節並刪除第二....(數據是烤麪包 - 你應該閱讀手冊....)
  3. 數據被破壞,沒有任何使用被保存...(數據是烤麪包 - 你應該已經閱讀手冊....)
  4. 一些其他選項,是我的心智能力以外.....

我已經將幾個不同的Unicode符號

INSERT INTO [Table] (Field1) 
VALUES ('') 

INSERT INTO [Table] (Field1) 
VALUES ('') 

,然後在這兩種情況下我得到了0x3F3F閱讀他們作爲一個字節SELECT cast (field1 as varbinary(10))後做了一些研究。

enter image description here

ascii3F?question mark)e.g兩個問號(??),我也看到在做正常時select *這是否意味着數據是烤麪包和連咬一號正在存儲?

超出排序規則的Unicode數據如何存儲在varchar列中?

回答

4

數據是烤麪包,正是你看到的,2×0x3F字節。這發生在插入之前的類型轉換期間,並且與cast('' as varbinary(2))一樣也是0xF3F3(與鑄造N''相反)。

當必須將Unicode數據插入非Unicode列時,通過使用WideCharToMultiByte API和與排序規則關聯的代碼頁,將內部列從Unicode轉換爲Unicode。如果在給定的代碼頁上不能表示字符,則該字符被問號(?)Ref替代。

+1

嗨,亞歷克斯,謝謝你的回答。我想知道爲什麼兩個'??'而不是1'?',感覺像是對傷害的侮辱,哈哈...... –

1

是的數據已經消失。

VarcharNVarchar相比需要更少的空間。但是這種減少是有代價的。 Varchar沒有空間存儲Unicode字符(每個字符1個字節,內部查找不夠大)。

Microsoft's Developer Network

...考慮使用Unicode的nchar或nvarchar數據類型以儘量減少字符轉換問題。

正如您發現的那樣,不支持的字符會使用問號進行回覆。

+0

這不是問題的大小;這是類型的定義和行爲,特別是隱式轉換。 nchar是一個UTF-16編碼單元;一些Unicode碼點需要一個,兩個。某些數據庫系統可以存儲爲UTF-8的Unicode,其中一個碼點需要一個,兩個,三個或四個8位代碼單元。 –

相關問題