19

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

我可以NLS_LANG使用SELECT USERENV ('language') FROM DUAL.

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

4

3 回答 3

9

这就是我在解决编码问题时所做的。(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)
于 2012-07-17T18:50:22.773 回答
5

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

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

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

于 2019-04-04T08:51:51.530 回答
3

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

variable n varchar2(200)

execute sys.dbms_system.get_env('NLS_LANG', :n )

print n

AMERICAN_AMERICA.WE8ISO8859P1

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

于 2018-01-19T13:47:38.853 回答