Поскольку набор символов базы данных - 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 .