線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:3842
推到 Plurk!
推到 Facebook!

MSSQL VARCHAR和NVARCHAR儲存UNICODE的字

缺席
老大仔
尊榮會員


發表:77
回覆:835
積分:1082
註冊:2006-07-06

發送簡訊給我
#1 引用回覆 回覆 發表時間:2013-08-02 16:39:25 IP:210.61.xxx.xxx 未訂閱
各位前輩大家好:
小弟目前對資料庫&編碼有些疑惑

在資料表:A_TEST 中建立兩個欄位:NAME1(Varchar)、NAME2(Nvarchar)
並新增兩筆資料:


此"峯"應屬為Unicode。
我知道Nvarchar可以儲存Unicode資料,

1. 第一筆資料的NAME2,為何是問號?雖然我知道有加N是將資料轉成Unicode,
但沒加的話就不是Unicode嗎? 假如不是的話,那是什麼碼?
2. 是否有什麼辦法可以將"峯"正確的存在Varchar中?
假如沒辦法的話,那麼退而求其次,是否可以在Select 時,將字碼正確顯示出來?
(我試過Convert和Cast是不行的...)
and在Delphi中有何辦法正確地顯示在DBGrid?
(因目前ERP系統的DB元件是採某廠商的ERP DB元件
所以無法用TNT元件取代掉)

因為小弟對編碼這塊完完全全的不熟
是否可以請哪位大大做詳細一點的解說...
(盡量深入淺出...我怕看不懂><)

不好意思...QQ

PS: 非常後悔前些日子 aftcast 蕭沖大的課程沒去聽...
(DB是MSSQL 2005)



編輯記錄
老大仔 重新編輯於 2013-08-02 16:42:18, 註解 無‧
aftcast
站務副站長


發表:81
回覆:1482
積分:1762
註冊:2002-11-21

發送簡訊給我
#2 引用回覆 回覆 發表時間:2013-08-02 17:55:48 IP:114.32.xxx.xxx 訂閱


>>>1. 第一筆資料的NAME2,為何是問號?雖然我知道有加N是將資料轉成Unicode,
>>> 但沒加的話就不是Unicode嗎? 假如不是的話,那是什麼碼?

照我的認知來說,沒加的話就是被寫入「?」這個字元的碼。



>>>2. 是否有什麼辦法可以將"峯"正確的存在Varchar中?

有機會,唯一的機會是存入utf8的字串…但要配套一些做法。而那些配套不是mssql本身(它完全對此無力),配套是你client 的程式。


>> and在Delphi中有何辦法正確地顯示在DBGrid?

有,只要你用d2009版以後的開發,天生的 ,delphi的string與mssql 的 nvarchar (再配合N""前置),完美的任何unicode都能呈現。


>>(因目前ERP系統的DB元件是採某廠商的ERP DB元件
>>所以無法用TNT元件取代掉)

照我看來,這才是禍首。請先確認那些db元件可否使用utf8,並若有能力再調查是否支持ucs2 (即windows的unicode)。這點沒確定的話,又不能不用的話,就完全無解!


>>是否可以請哪位大大做詳細一點的解說...
>>(盡量深入淺出...我怕看不懂><)

我時間太少,近期過忙,很難深入x出,若有其他前輩也懂,也請其他前輩多來幫忙,我算拋磚引玉好了…





------



蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
aftcast
站務副站長


發表:81
回覆:1482
積分:1762
註冊:2002-11-21

發送簡訊給我
#3 引用回覆 回覆 發表時間:2013-08-04 19:44:37 IP:114.42.xxx.xxx 訂閱


>>>1. 第一筆資料的NAME2,為何是問號?雖然我知道有加N是將資料轉成Unicode,
>>> 但沒加的話就不是Unicode嗎? 假如不是的話,那是什麼碼?

照我的認知來說,沒加的話就是被寫入「?」這個字元的碼。



>>>2. 是否有什麼辦法可以將"峯"正確的存在Varchar中?

有機會,唯一的機會是存入utf8的字串…但要配套一些做法。而那些配套不是mssql本身(它完全對此無力),配套是你client 的程式。


>> and在Delphi中有何辦法正確地顯示在DBGrid?

有,只要你用d2009版以後的開發,天生的 ,delphi的string與mssql 的 nvarchar (再配合N""前置),完美的任何unicode都能呈現。


>>(因目前ERP系統的DB元件是採某廠商的ERP DB元件
>>所以無法用TNT元件取代掉)

照我看來,這才是禍首。請先確認那些db元件可否使用utf8,並若有能力再調查是否支持ucs2 (即windows的unicode)。這點沒確定的話,又不能不用的話,就完全無解!


>>是否可以請哪位大大做詳細一點的解說...
>>(盡量深入淺出...我怕看不懂><)

我時間太少,近期過忙,很難深入x出,若有其他前輩也懂,也請其他前輩多來幫忙,我算拋磚引玉好了…





------



蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
leveon
資深會員


發表:29
回覆:386
積分:303
註冊:2012-02-12

發送簡訊給我
#4 引用回覆 回覆 發表時間:2013-08-05 10:53:47 IP:114.35.xxx.xxx 訂閱
 節錄:
http://miggo.pixnet.net/blog/post/30246441-windows系統之繁體nls-file(c_950.nls)拆解
提一些Windows編碼的基本概念
Window 2000以後之系統,皆以Unicode當成基礎
各地區之編碼就是以NLS File進行對應
System32\c_950.nls 就是繁體中文的對照檔
無Big5定義部分,對照是? (0x003F)
--------------------------------------------------------
這就是一直會出現 ? 的原因
只要去修改 NLS 對應檔 把缺字補完 就可以正確顯示了
這也是 xx補完計劃在做的事
更多細節可以google "c_950.nls"
如果要在舊VCL上顯示出缺字 如果不套用OS系統機制
也應該自建對照檔 比對後 自行畫在螢幕上 那也很麻煩
補完路線似乎比較穩定簡單
sryang
尊榮會員


發表:38
回覆:741
積分:875
註冊:2002-06-27

發送簡訊給我
#5 引用回覆 回覆 發表時間:2013-08-06 11:41:40 IP:202.134.xxx.xxx 訂閱
 「補完計畫」就好像病毒一樣,一人感染,全家中鏢

你用補完計畫存進去的非 BIG5 範圍的文字,別人看不見,除非他也裝補完計畫,使得大家都得裝補完計畫

更慘的是,「補完計畫」只對非 Unicode 程式有效,如果日後程式升級成支援 Unicode,以前用「補完計畫」

存進去的非 BIG5 範圍的字,用 Unicode 程式讀出來完全變成兩回事,還得花時間轉換回正確的 Unicode 碼

~~~只能在腿上寫個慘字了~~~
------
歡迎參訪 "腦殘賤貓的備忘錄" http://maolaoda.blogspot.com/
編輯記錄
sryang 重新編輯於 2013-08-06 11:43:02, 註解 無‧
sryang 重新編輯於 2013-08-06 11:44:00, 註解 無‧
leveon
資深會員


發表:29
回覆:386
積分:303
註冊:2012-02-12

發送簡訊給我
#6 引用回覆 回覆 發表時間:2013-08-06 21:23:28 IP:111.241.xxx.xxx 訂閱
摘自wiki

http://zh.wikipedia.org/wiki/Unicode補完計畫
「Unicode補完計畫」讓這些字元保持了雙向流通性。在補完後的電腦上,當這些字元從大五碼轉變到Unicode儲存後,它們全都會被對應到正確的Unicode位置上,之後即使是對於沒有安裝補完計畫的電腦使用者,只要他的系統和程式支援Unicode,在讀取這些文字時,就完全沒有問題。



補完計畫與造字最大不同 就是他採用雙向對應 等你升級新版Delphi
在"有裝補完"的電腦上把舊碼轉存成Unicode
應該可以無誤的轉成Unicode 你的情況應該是沒裝補完的情況下就進行轉檔

最完美情況當然是放棄Big5
但凡事都有代價 要怎樣都可以 剩下的只是成本和取捨問題而已


===================引 用 sryang 文 章===================
「補完計畫」就好像病毒一樣,一人感染,全家中鏢

你用補完計畫存進去的非 BIG5 範圍的文字,別人看不見,除非他也裝補完計畫,使得大家都得裝補完計畫

更慘的是,「補完計畫」只對非 Unicode 程式有效,如果日後程式升級成支援 Unicode,以前用「補完計畫」

存進去的非 BIG5 範圍的字,用 Unicode 程式讀出來完全變成兩回事,還得花時間轉換回正確的 Unicode 碼

~~~只能在腿上寫個慘字了~~~
Victor4022
中階會員


發表:0
回覆:76
積分:90
註冊:2011-02-20

發送簡訊給我
#7 引用回覆 回覆 發表時間:2013-08-08 21:42:20 IP:106.107.xxx.xxx 訂閱
VARCHAR 型別是當前 Database 的預設編碼,通常如果沒額外設定,會繼承自 SQL Server 的編碼,而 SQL Server 安裝時就有選擇預設編碼。
以您的情境來說,可能 VARCHAR 假設是 Big-5 code,"峯" 這個字在 Utf-16 LE 編碼是 0x5CEF,但 Big-5 編碼區域內沒有針對這個字的字體呈現,因此被 SQL Server 以 "?" 字樣取代,但第二個欄位指定成 NVARCHAR 表示該欄位內容為寬字元版本,在 INSERT 時必須配合加上 N 修飾詞,才會以 Utf-16LE 編碼寫入資料庫。

換言之,要用 VARCHAR 欄位形別去儲存 Big-5 code (或是該字碼範圍內沒有含概的其他編碼),就一定會變成 "?" 字元。
在 Delphi 2009 之前內建的 VCL 都不支援 Unicode ,您這題在不更換支援 Unicode 的 VCL 前提下,應該是無解。 (因為字元編碼在 SQL 回傳到 AP 的傳輸過程已經跑掉)

另外一個搞笑的建議,其實可以用 IMAGE 或 BINARY 方式去儲存 Unicode 字串資料,查詢出來時以 WideString 承接內容,但還是回到 UI 呈現的議題,要有支援 Unicode VCL 才能正確呈現編碼內容。 (這個建議是沒有用的,逃~~~~)


===================引 用 老大仔 文 章===================
各位前輩大家好:
小弟目前對資料庫&編碼有些疑惑

在資料表:A_TEST 中建立兩個欄位:NAME1(Varchar)、NAME2(Nvarchar)
並新增兩筆資料:


此"峯"應屬為Unicode。
我知道Nvarchar可以儲存Unicode資料,

1. 第一筆資料的NAME2,為何是問號?雖然我知道有加N是將資料轉成Unicode,
但沒加的話就不是Unicode嗎? 假如不是的話,那是什麼碼?
2. 是否有什麼辦法可以將"峯"正確的存在Varchar中?
假如沒辦法的話,那麼退而求其次,是否可以在Select 時,將字碼正確顯示出來?
(我試過Convert和Cast是不行的...)
and在Delphi中有何辦法正確地顯示在DBGrid?
(因目前ERP系統的DB元件是採某廠商的ERP DB元件
所以無法用TNT元件取代掉)

因為小弟對編碼這塊完完全全的不熟
是否可以請哪位大大做詳細一點的解說...
(盡量深入淺出...我怕看不懂><)

不好意思...QQ

PS: 非常後悔前些日子 aftcast 蕭沖大的課程沒去聽...
(DB是MSSQL 2005)



系統時間:2017-10-21 16:36:31
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!