【问题标题】:How do I check the NLS_LANG of the client?如何检查客户端的 NLS_LANG?
【发布时间】:2012-07-17 12:48:21
【问题描述】:

我正在使用 Windows 操作系统,我知道此设置存储在注册表中。问题是注册表路径会随着版本的变化而变化,浏览那一堆注册表项绝对不是一个好主意。

我可以通过SELECT USERENV ('language') FROM DUAL 获取服务器的NLS_LANG

我想将其与客户端设置进行比较,并在它们不匹配时显示警告,就像 Pl/Sql Developer 所做的那样。

【问题讨论】:

  • 您是否查看过 NLS_SESSION_PARAMETERS、NLS_DATABASE_PARAMETERS 和 NLS_INSTANCE_PARAMETERS? docs.oracle.com/cd/E11882_01/server.112/e25513.pdf
  • 好吧,他们给了我一切……除了客户端的 NLS_LANG
  • 会话视图是否没有提供您要查找的内容? select * from nls_session_parameters where parameter = 'NLS_LANGUAGE';更改会话集 nls_language=german; select * from nls_session_parameters where parameter = 'NLS_LANGUAGE';
  • 你在客户端使用什么接口?
  • @Glenn 这只是信息的一部分。 NLS_LANG 给了我_.。 NLS_LANGUAGE 带来的是语言和地域,而不是字符集,这对我来说是最重要的。

标签: oracle character-encoding nls-lang


【解决方案1】:

这就是我在解决编码问题时所做的。 (sqlplus读取的NLS_LANG值):

SQL>/* It's a hack. I don't know why it works. But it does!*/
SQL>@[%NLS_LANG%]
SP2-0310: unable to open file "[NORWEGIAN_NORWAY.WE8MSWIN1252]" 

必须从注册表中提取当前 ORACLE_HOME 中的 NLS_LANG 值。 所有客户端工具(sqlplus、sqlldr、exp、imp、oci 等)从注册表中读取此值 并确定是否应进行任何字符转码。

ORACLE_HOME 和注册表部分:

C:\>dir /s/b oracle.key
C:\Oracle10\BIN\oracle.key

C:\>type C:\Oracle10\BIN\oracle.key
SOFTWARE\ORACLE\KEY_OraClient10204_Home

在这种情况下,我求助于 IPython 来展示一个想法:

进行几次查找,您就在那里!

In [36]: OHOMES_INSTALLED = !where oci.dll

In [37]: OHOMES_INSTALLED
Out[37]:
['C:\\Oracle10\\BIN\\oci.dll',
'C:\\oraclexe\\app\\oracle\\product\\11.2.0\\server\\bin\\oci.dll']

In [38]: ORACLE_HOME = os.path.dirname(OHOMES_INSTALLED[0])

In [39]: ORACLE_HOME
Out[39]: 'C:\\Oracle10\\BIN'

In [40]: f = open(os.path.join(ORACLE_HOME, "oracle.key"))

In [41]: SECTION = f.read()

In [42]: SECTION
Out[42]: 'SOFTWARE\\ORACLE\\KEY_OraClient10204_Home\n'

In [43]: from _winreg import *

In [44]: aReg = ConnectRegistry(None,HKEY_LOCAL_MACHINE)

In [46]: aKey = OpenKey(aReg,SECTION.strip())

In [47]: val = QueryValueEx(aKey, "NLS_LANG")

In [48]: print val
(u'NORWEGIAN_NORWAY.WE8MSWIN1252', 1)

【讨论】:

  • 谢谢,这是一种解决方法。不幸的是,我不能那样做。我只想快速检查一下。在 HD 中进行完整搜索会找到答案,但需要的时间太长(而且,它并不那个可靠,可能还有其他具有该名称的文件)。所以,如果我理解正确,没有简单的方法。我必须浏览每个新版本都会更改位置的疯狂注册表项。是对的吗?在那种情况下,我想我会放弃它。这不值得努力。
【解决方案2】:

根据 Jocke 的回答(感谢 Jocke),我测试了以下查询:

SELECT DISTINCT client_charset FROM v$session_connect_info
WHERE sid = sys_context('USERENV','SID');

它完美地完成了这项工作,但我不确定是否有任何用户拥有必要的权限。

【讨论】:

    【解决方案3】:

    我不确定这是否每次都有效,但在 sql*plus 中对我来说:

    variable n varchar2(200)
    
    execute sys.dbms_system.get_env('NLS_LANG', :n )
    
    print n
    
    AMERICAN_AMERICA.WE8ISO8859P1
    

    只需构建一个函数包装器,将执行权限授予需要它的用户,然后就可以了。

    【讨论】:

    • 经过一些测试。 GET_ENV 不是从客户端获取参数,而是从服务器进程获取参数。所以它没有像我希望的那样工作。对不起:-(
    • 经过一番挖掘,我发现数据库实际上存储了每个连接会话的客户端字符集:SELECT sid, client_charset FROM v$session_connect_info;
    猜你喜欢
    • 2011-09-08
    • 2014-06-04
    • 2016-03-04
    • 1970-01-01
    • 2012-04-10
    • 2011-04-27
    • 2013-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多