Как проверить NLS_LANG клиента?

Я работаю над ОС Windows, я знаю, что этот параметр хранится в реестре. Проблема в том, что путь к реестру изменяется от версии к версии, просматривая, хотя эта группа ключей реестра определенно не очень хорошая идея.

Я могу получить NLS_LANG сервера с SELECT USERENV ('language') FROM DUAL.

Я бы хотел сравнить это с настройкой клиента и показать предупреждение, когда они не совпадают, как это делает Pl/Sql Developer.

Ответ 1

Это то, что я делаю, когда я устраняю проблемы с кодировкой. (Значение NLS_LANG, считанное sqlplus):

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

Вам будет нужно извлечь значение NLS_LANG в текущем ORACLE_HOME из реестра. Все клиентские инструменты (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)

Ответ 2

Я не уверен, работает ли это каждый раз, но для меня в sql * plus:

variable n varchar2(200)

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

print n

AMERICAN_AMERICA.WE8ISO8859P1

Просто создайте функцию-обертку, предоставьте execute пользователям, которые в ней нуждаются, и все готово.

Ответ 3

Согласно ответу Джока (спасибо Джокку), я проверил следующий запрос:

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

Он отлично справляется со своей задачей, но я не уверен, что у любого пользователя будут необходимые права.