[SQL] 資料欄位採用 varchar 和 nvarchar 情況下的處理 unicode 資料問題

[SQL] 資料欄位採用 varchar & nvarchar 情況下的處理 unicode 資料問題

早上有朋友詢問了一個好玩的問題,這一陣子也遇到一些朋友都有點搞混,因此我將它的問題稍微調整一下,做一個範例還展示一下。

 

首先我先建立一個測試用的資料表來存放資料,並且存放兩筆資料到資料表內,存放的時候是會一筆如同舊的寫法存入字串,另一筆則是會在字串前面加入 N 表示為 Unicode


-- 建立範例資料表
CREATE TABLE A1 ( F1 int, F2 varchar(10), F3 nvarchar(10) )
GO

-- 存入範例資料
INSERT INTO A1 VALUES ( 1 , '堃', '堃' );
INSERT INTO A1 VALUES ( 2 , N'堃', N'堃' );
GO

 

而當我們下 select 條件取出資料的時候,則看起來似乎有些不正確,為了能說明,因此我稍微做了一點調整


SELECT 
  *,CAST(F2 AS varbinary ) F2_BIN,CAST(F3 AS varbinary ) F3_BIN  
FROM A1

 

顯示結果如下

image

 

從圖上可以看到,當我們如果將一個資料,如果你沒有特別指定要採用 UNICODE ,也就是字串前面加入 N 的標示的情況下,不論你是否欄位採用可以儲存 UNICODE 型態的 nchar 或者是 nvarchar ,資料都會因為作業系統採用 DBCS (Double Byte Character Set,DBCS)  的方式,將資料給存入。但就算你有加入 N 的提示,也一定要來欄位有支援 Unicode,否則資料還是會轉換成為 DBCS。

 

因此針對上述的狀況,我們再來做個簡單的測試


-- Step 1
SELECT * FROM A1 WHERE F2 = '堃'
GO
 
-- Step 2
SELECT * FROM A1 WHERE F2 = N'堃'
GO

 

結果會有點特別,因為資料存到 F2 欄位 ( varchar ) 的時候因為欄位不是 UNICODE 的型態,因此在前面存入的時候就已經用 DBCS 的方式轉碼了,所以我們下條件的時候沒有加入 N 的提示,就會找到兩筆符合的資料,但要是加入 N 的話,反而會找不到任何資料。

image

 

但如果我們改針對 F3 的欄位 ( nvarchar ) 下了類似的指令,那麼結果會如何呢 ?


-- Step 3
SELECT * FROM A1 WHERE F3 = '堃'
GO

-- Step 4
SELECT * FROM A1 WHERE F3 = N'堃'
GO

則結果會各自都只有一筆符合的紀錄

image

 

從上述的範例中,只是想說明一件事情,資料庫欄位要注意所使用的欄位型態,而且在使用的時候,也要特別注意,不要覺得執行沒有錯誤,就忽略到這些細節,那可能會造成後續更多的麻煩。