我想出瞭如何讓文本以.net形式正確顯示。它實際上與字體無關,而且更多的是爲.net轉換數據。我已經改變了代碼,基本上是這樣的:
string Name = reader.GetString(column);
到
string Name = System.Text.Encoding.Default.GetString(reader.GetOracleString(column).GetNonUnicodeBytes());
我仍然要確認這不會導致問題,任何其他語言的客戶端使用的是已經工作的罰款,但到目前爲止希臘語和英語看起來不錯。
現在我需要在添加用於保存的OracleCommand參數時反轉該過程。原來的代碼是這樣的:
cmd.Parameters.Add(new OracleParameter(":name", Name));
它節省垃圾。字符串「Name」的值看起來很好。工作的非託管C++代碼只是將一個sql語句放在一個字符數組中(希臘文本總是在一個char數組中處理),並通過調用OCI函數(Oracle的API)來執行它。 .net代碼使用ODAC(Oracle數據訪問客戶端)進行數據庫訪問。
UPDATE:
我已經解決了我的問題(保存)的第二部分,更多地瞭解正在發生的事情。
的數據來從甲骨文到.NET看起來像這樣在內存中,當我把它變成一個.NET字符串數據類型,而不做任何轉換:
00 0A 33 79 07 00 00 00 06 00 00 00 d4 00 e1 00 ec 00 e5 00 df 00 ef 00 00 00 00 00 00 00 00 00 00 00 00 ..3y ........t.α.μ.ε.ί.ο..... .......
此字符串顯示不正確在.NET爲:
Ôáìåßï
在.NET字符串的存儲器內容轉換後(轉化如上所示代碼):
00 0a 33 79 07 00 00 00 06 00 00 00 a4 03 b1 03 bc 03 b5 03 af 03 bf 03 00 00 00 00 00 00 00 00 00 00 00 .3y ........¤。 ±.Ό.μ.-。.... ............
您可以看到,對於每個字符,已從低位字節的高半字節中取出3,並將其置於高位字節。
字符串現在顯示正確.NET爲:
Ταμείο
如以上示出了信息,似乎.NET不同表示字符比非託管C++和Oracle。我做了一些測試,發現突破點是160(十六進制值a0)。所以當使用0到159(00到9f)的字符值時,沒有區別。一旦使用160或更高的值,就會有所不同。
我的解決方案只適用於0到255之間的字符值,因爲我在轉換中刪除了字符的高字節。這應該適用於我們的應用程序,儘管我們從來不支持多字節字符集。
我在做字符串轉換回的格式保存到Oracle什麼簡化版本是:
//"name" represents a .net string data type containing the data to save
char[] textChars = new char[4000]; //4000 is the max varchar2 column size in Oracle
byte[] textBytes;
int index = 0;
textBytes = (System.Text.Encoding.Default.GetBytes((name).ToCharArray()));
foreach (byte textByte in textBytes)
{
textChars[index++] = (char)textByte;
}
string textString = new string(textChars, 0, index);
cmd.Parameters.Add(new OracleParameter(":name", (object)(textString)));
這整個事情是這樣的黑客 - 如果任何人有一個更好的辦法,請分享它。似乎應該有一些簡單的方法來處理整個問題。
我很確定我的項目已經在使用Unicode。這就是爲什麼如果我從.net窗體獲取文本並將其粘貼到zApp窗體中,那很好。這些角色的數據不會丟失。但只是爲了測試你的建議,我添加了一個帶有按鈕的新表單,並沒有任何提示切換到Unicode。它以同樣的方式顯示 - 如果我從我的鍵盤輸入希臘語,它會顯示正常,但數據庫中的希臘語和zApp格式不顯示。 – AAyres 2009-08-04 18:40:01
根據我已閱讀的有關WE8ISO8859P1的內容,我在Oracle數據庫中使用的字符應始終爲單個字節長度。 – AAyres 2009-08-06 16:32:50