2012-09-27 85 views
2

我遇到了嚴重的字符編碼問題。給一些背景:西班牙語字符集到土耳其語sql

  1. 我有在土耳其語言的Unix屏幕上輸入一些數據的土耳其商業用戶。
  2. 我的數據庫NLS參數設置爲AMERICAN,WE8ISO8859P1和Unix NLS_LANGAMERICAN_AMERICA.WE8ISO8859P1
  3. 土耳其的企業能夠看到UNIX屏幕和蟾蜍所有的土耳其字符,而我不是。我只能在西歐字符集中看到它們。

在營業結束:ÖZER İNŞAAT TAAHHÜT VE
在我們結束:ÖZER ÝNÞAAT TAAHHÜT VE

如果您發現土耳其字符İŞ越來越轉換爲ISO 8859-1字符集。但是,所有設置(db和unix中的NLS參數)在兩端都是相同的 - ISO8859-1(西歐)

通過一些研究,我可以理解 - 土耳其機器可以通過實時轉換顯示土耳其數據( DB NLS設置由本地NLS設置覆蓋)。

現在,我有一個接口,在我的DB-運行有一定的PL/SQL腳本(通過shell腳本運行),從數據庫中提取一些數據,並將它們脫機到UNIX路徑上的.csv文件。然後,.csv文件通過MFT(託管文件傳輸)傳輸到外部系統。

的問題是 - Exract從未conains任何土耳其語字符。每個土耳其角色都被轉換成西歐文字,並且像這樣進入外部系統,這被視爲數據轉換/丟失的情況,我的業務真的很不愉快。

誰能告訴我 - 我怎麼會保留所有的土耳其字符?

P.S. :外部系統的字符集可以設置爲ISP8859-9字符集。

非常感謝提前。

回答

5

如果你說你的數據庫字符集是ISO-8859-1,即

SELECT parameter, value 
    FROM v$nls_parameters 
WHERE parameter = 'NLS_CHARACTERSET' 

返回WE8ISO8859P1一個value,你是存儲CHAR數據,VARCHAR,或VARCHAR2列,問題數據庫字符集不支持全套土耳其字符。如果一個字符不在ISO-8859-1 codepage layout中,則它不能正確存儲在由數據庫字符集管理的數據庫列中。如果要將土耳其語數據存儲在ISO-8859-1數據庫中,則可以使用workaround characters(即用S代替Ş)。但是,如果要支持全部土耳其字符,則需要移至支持所有這些字符的字符集 - ISO-8859-9或UTF-8將是相對常見的。

更改字符集現有數據庫的是一個不平凡的事業,但是。全球化支持指南中有一章介紹了您使用的任何版本的Oracle,包括character set migration。如果要移動到Unicode字符集(通常是首選方法,而不是堅持使用單字節ISO字符集之一),則可以使用Oracle Database Migration Assistant for Unicode

此時,您通常會看到反對意見,即至少某些應用程序正在「正確」看到數據,因此數據庫必須支持土耳其字符。問題是如果你使用set up your NLS_LANG incorrectly,可以完全繞過字符集轉換,這意味着客戶端上任何字符的二進制表示都可以在不修改數據庫的情況下持久化。只要讀取數據的每個進程以相同和不正確的方式配置NLS_LANG,事情似乎就可以奏效。但是,您將很快發現某些其他應用程序將無法正確配置NLS_LANG。例如,Java應用程序總是希望將數據庫中的數據轉換爲內部的Unicode字符串。因此,如果您將數據錯誤地存儲在數據庫中,就像您聽起來一樣,無法讓這些應用程序正確讀取它。如果您只是在shell腳本中使用SQL * Plus來生成文件,幾乎肯定可能會錯誤地配置您的客戶端,以使數據文件看起來是正確的。但是,讓現有的錯誤配置依然存在是一個非常糟糕的主意。你打開自己很多將來會遇到更大的問題(如果你還沒有在那裏),不同的客戶端將不同的字符集中的數據插入到數據庫中,這使得解開起來更加困難,當你發現諸如Oracle導出實用程序已損壞導出的數據或想要使用無法錯誤配置的工具查看數據。提前解決問題的能力會更好。

+0

感謝您的專家意見。但由於某些限制,我無法更改我的db nls_characterset參數。有沒有辦法通過在unix shell中設置nls_lang或locale來發送這些字符? 因爲我已經嘗試將'NLS_LANG'設置爲''TURKISH_TURKEY.WE8ISO8859P9',但它似乎已經給出了'?'(問號)而不是土耳其文字符,即使文件已被MFT選中併發送到外部系統。 – prashant1988