2012-09-27 53 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