Проблемы с кодировкой латинских символов в таблице Oracle - PullRequest
0 голосов
/ 20 ноября 2018

У меня есть база данных оракула с

NLS_CHARACTERSET=AL32UTF8  

sqlplus nls_lang is WE8ISO8859P1

unix shell iso aswell

Есть столбец varchar2 с буквой: МАЛЕНЬКОЕ ПИСЬМО ЛАТИНА O С ОСТРОМ

Когда я вызываю функцию DUMP для этого столбца, я получаю:

Typ=1 Len=4: 195,131,194,179

Это не похоже на UTF8.

При запуске SELECT на экране отображается поврежденный канал.

Running CONVERT(VALUE, 'WE8ISO8859P1', 'UTF8') - показывает правильное значение, но кодировка не выглядит как UTF8 ...


Если я пытаюсь вставить ту же букву вручную, запрос на выборку возвращает правильный символ.

Дамп показывает 195 179, что является правильным кодом UTF8.

Запуск CONVERT(VALUE, 'WE8ISO8859P1', 'UTF8') - сбой
ORA-29275: частичный многобайтовый символ

Что странно, поскольку 195 179действительно UTF8.

Пожалуйста, объясните мне выше.

1 Ответ

0 голосов
/ 20 ноября 2018

Значение Typ=1 Len=4 CharacterSet=AL32UTF8: c3,83,c2,b3 было явно вставлено неправильно.

Это произошло, когда клиент отправил символы как UTF-8, но база данных обработала эти данные как WE8ISO8859P1.

Если клиент отправляет данныев качестве UTF-8 вы также должны установить NLS_LANG=.AL32UTF8 (язык и территория необязательны и здесь не имеют значения).

Однако при запуске sqlplus sqlplus наследует набор символов из командной строки, который выглядит как ISO 8859-1.Поэтому, прежде чем запускать sqlplus, вы должны запустить export NLS_LANG=.WE8ISO8859P1, чтобы правильно установить его.

Я создаю таблицу с вашими данными:

SELECT 
    val, 
    DUMP(val, 1016) as dump_val, 
    DUMP(CONVERT(VAL, 'WE8ISO8859P1'), 1016) as conv_dump
FROM AA;


+-------------------------------------------------------------------------------------------+
|VAL|DUMP_VAL                                      |CONV_DUMP                               |
+-------------------------------------------------------------------------------------------+
|ó |Typ=1 Len=4 CharacterSet=AL32UTF8: c3,83,c2,b3|Typ=1 Len=2 CharacterSet=AL32UTF8: c3,b3|
|ó  |Typ=1 Len=2 CharacterSet=AL32UTF8: c3,b3      |Typ=1 Len=1 CharacterSet=AL32UTF8: f3   |
+-------------------------------------------------------------------------------------------+

Строка 1 показывает поврежденные данные, строка 2 - этоотлично.

CONVERT(VAL, 'WE8ISO8859P1') используется для преобразования поврежденных данных в правильный набор символов, поэтому преобразование CONVERT(UTL_RAW.CAST_TO_VARCHAR2('C383C2B3'), 'WE8ISO8859P1') в порядке.

Однако CONVERT(UTL_RAW.CAST_TO_VARCHAR2('C3B3'), 'WE8ISO8859P1') вернет шестнадцатеричный F3, что недействительная последовательность байтов UTF-8, таким образом, вы получаете ORA-29275.

...