Oracle настроил NLS_LANG по умолчанию - PullRequest
3 голосов
/ 15 марта 2012

Я использую базу данных Oracle 11g на RHEL6.Если нет клиента NLS_LANG, установите длину некоторого символа utf8 равным 2. После того, как NLS_LANG = AMERICAN_AMERICA.UTF8 установлена, длина составляет только 1. Как можно поставить ставку, измененную по умолчанию, NLG_LANG для всей базы данных?Я не хочу изменять это значение только для сеанса или как переменная окружения в Linux.Есть ли возможность установить его для базы данных вообще?

SQL> select length('á') from dual;

LENGTH('??')
------------
           2

# export NLS_LANG=AMERICAN_AMERICA.UTF8

SQL> select length('á') from dual;

LENGTH('á')
-----------
          1

Большое спасибо за любую идею

Ответы [ 2 ]

2 голосов
/ 15 марта 2012

Вот что, вероятно, происходит:

  • Ваш клиентский набор символов должен быть чем-то вроде CP1252 или ISO-8859-15, тогда как на самом деле ваш клиент действительно использует UTF8.
  • В этомнабор символов (UTF8), символ á занимает два байта, поэтому ваш клиент отправляет эти два байта, в то же время говоря Oracle обрабатывать их как CP1252.В CP1252 двухбайтовый код для двух символов, в результате чего БД интерпретирует ввод как два символа, поэтому length('à') равно 2 (и если вы вставите эту строку, результат вставки не будет равен à)
  • Когда вы правильно установите набор символов, ввод правильно обрабатывается оракулом как один символ, и его длина равна 1 (все еще два байта).

Вывод: установите свой набор символов клиентаправильно или вы получите ошибки перевода (вы не получите недопустимые символы таким образом, но вы можете получить странные символы (¿).

Набор символов базы данных устанавливается во время создания и обычно изменяетсячерез экспорт / создать пустую базу данных / импорт.

1 голос
/ 15 марта 2012

Поскольку набор символов базы данных - AL32UTF8, когда вы устанавливаете для клиента NLS_LANG значение UTF8, вы говорите Oracle об обходе преобразования набора символов, которое обычно происходит при передаче данных между клиентом и сервером.Это чрезвычайно опасно, потому что это означает, что если клиент отправляет данные в любой другой кодировке, существует значительный риск того, что недействительные данные будут сохранены в базе данных.В этом случае вызов LENGTH, который возвращает 1, отправляет неправильно закодированные данные в базу данных.Скорее всего, клиентская операционная система представляет данные, используя что-то вроде набора символов ISO-8859-1, где á - однобайтовый символ (двоичное значение 0xE1).Когда клиент отправляет данные в базу данных, он отправляет 0xE1 и сообщает базе данных: «Поверьте мне, это действительные данные UTF-8».База данных не пытается проверить двоичные данные, чтобы заметить, что 0xE1 не является допустимым двоичным представлением любого символа в наборе символов UTF-8.Но теперь, если появляется другой клиент, который правильно настроен и запрашивает преобразование набора символов, и в базе данных хранится 0xE1, сохраненный в некотором столбце, будет запущен код преобразования набора символов, идентифицирующий, что 0xE1 не является допустимым UTF-8символ и вернуть символ замены (обычно '?'), а не á правильно настроенному клиенту.

Так как набор символов базы данных - UTF-8, можно ожидать, что символ 'á' будет иметьдлина 2. UTF-8 - набор символов переменной ширины.Символы, которые являются частью набора символов US7ASCII, представлены 1 байтом, большинство западноевропейских символов, таких как «á», представлены с использованием 2 байтов, а большинство азиатских символов представлено с использованием 3 байтов.Есть несколько редких символов, которые требуют 4 байта.

Ваш NLS_LANG должен быть установлен в соответствии с набором символов, который поддерживает ваша клиентская система.Редко, когда у вас есть клиентская система с поддержкой UTF-8.Поскольку настройки вашего клиента будут переопределять все, что установлено на уровне базы данных, это означает, что каждый клиент должен быть настроен для установки соответствующей переменной среды.В NLS_LANG FAQ на есть раздел, как определить правильную настройку NLS_LANG для клиента Unix .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...