как узнать кодировку oracle
StasyakOFF Blog
Настраиваем NLS_LANG для PLSQL Developer
Для диагностики проблемы необходимо включить проверку кодировки в PLSQL Developer
Картинка 1.
Пытаемся подключиться к базе.
У меня появилось такое вот полезное предупреждение:
Картинка 3.
Тут необходимо рассказать предысторию. Когда я столкнулся с, описанной в начале поста, проблемой, то решил сразу погуглить. А нагуглилось там в принципе правильное решение установить корректное значение NLS_LANG, однако найти алгоритм такой «корректной» настройки мне так и не удалось. Далее, 9 из 10 статей предлагали сделать изменение в реестре в ветке
\HKEY_LOCAL_MACHINE\Software\ORACLE, некоторые авторы шли дальше и предлагали изменить еще и все NLS_LANG во вложенных ветках. Возможно эти советы кому-то и помогли, но я перепробовав все эти советы получил нулевой результат.
Тут я и нашел настройку plsql developer, которая включает проверку соответствия кодировок клиента и сервера (Картинки 1 и 2). При подключении к серверу я получил предупреждение (Картинка 3), которое оказалось, мягко говоря, неожиданным. plsql developer утверждал что пытается читать NLS_LANG из не существующей ветки. Т.к. regedit у меня уже был открыт, то я просто добавил новую ветку и NLS_LANG, перезагрузил plsql developer и. получил все тоже предупреждение. Я не стану утверждать что этот вариант не рабочий и его пробовать не стоит, но у меня решение с реестром не взлетело почему-то.
Оставалось добавить NLS_LANG в виде переменной окружения. После перезапуска plsql developer все заработало как надо.
Картинка 4.
Для справки:
Чтобы посмотреть текущую кодировку БД надо выполнить в plsql developer в меню File->New->SQL Window команду
SELECT * FROM NLS_DATABASE_PARAMETERS;
Кодировка клиента:
SELECT * FROM NLS_SESSION_PARAMETERS;
FAQ по ORACLE
Проблемы кодировки
Вопрос: Подскажите, как получить в Oracle список всех первичных ключей в виде: [id_column], [id_table]
Ответ: select col.column_name,con.table_name from user_constraints con,user_cons_columns col where col.constraint_name=con.constraint_name and con.constraint_type=’P’;
Вопрос:Как правильно выбрать кодовую страницу при инсталляции?
Ответ: Cпособы корректной установки поддержки национальных кодировок и стандартов в продуктах Oraclе обсуждались в статье С. Мосина [Oracle Magazine/Russian Edition номер 1 за лето 1996]
При инсталляции необходимо выбирать «Русский», даже если это пробная установка.
Однако часто еще встречаются СУБД Oracle с установленной CHARSET=WE8ISO8859P1 по умолчанию. Иногда это делается по незнанию, чаще с мыслью, что эта инсталляция временна, никогда не поздно будет изменить; а некоторые версии, например, распространявшаяся через Интернет trial версия Personal Oracle for Windows 3.1, не имели локальных кодировок.
К сожалению Oracle Corp. не предусмотрела легальных (документированных) способов изменения кодировок СУБД и приложений
Вопрос:Как можно решить проблемы, связанные с неверно заданной кодовой страницей?
Перекодировки данных здесь не происходит, изменяется только пометка для Oracle. Вы должны точно представлять в какой кодировке ваши данные находятся.
Прежде, чем использовать этот метод проверьте, присутствует ли необходимая вам кодировка в списке допустимых :
Текущие установки NLS БД можно просмотреть используя view NLS_DATABASE_PARAMETERS. Что представляет из себя это view?
SQL> select text from dba_views where view_name=’NLS_DATABASE_PARAMETERS’;
where name like ‘NLS%’
SQL> select * from props$ where name=’NLS_CHARACTERSET’;
NAME VALUE$ COMMENT$
NLS_CHARACTERSET WE8ISO8859P1 Character set
SQL> select * from props$ where name like ‘NLS_CHARACTERSET’;
NAME VALUE$ COMMENT$
NLS_CHARACTERSET CL8MSWIN1251 Character set
Как решить проблемы, возникающие при осуществлении экспорта в системе с кодировкой WE8ISO8859P1, а импорта на системе с русской кодировкой?
Использование параметра CHARSET применимо для импорта данных из версий ранее 7 (Oracle 5, 6). Экспортный файл версии 7 содержит в себе информацию о кодировке данных, из-за чего и возникают проблемы. Как же этого избежать?
Необходимо изменить этот байт с помощью любого шестнадцатеричного редактора.
Советы Игоря Филимонова ЛАСУ ТРИНИТИ, г. Троицк (Oracle Club)
За дополнительной информацией обращайтесь в компанию Interface Ltd.
Oracle как посмотреть кодировку базы
Вопрос: Подскажите, как получить в Oracle список всех первичных ключей в виде: [id_column], [id_table]
Ответ: select col.column_name,con.table_name from user_constraints con,user_cons_columns col where col.constraint_name=con.constraint_name and con.constraint_type=’P’;
Это будет поименный перечень. Идентификаторы таблиц можно взять из user_tables, а столбцов — из user_tab_columns.
Вопрос:Как правильно выбрать кодовую страницу при инсталляции?
Ответ: Cпособы корректной установки поддержки национальных кодировок и стандартов в продуктах Oraclе обсуждались в статье С. Мосина [Oracle Magazine/Russian Edition номер 1 за лето 1996]
При инсталляции необходимо выбирать «Русский», даже если это пробная установка.
Однако часто еще встречаются СУБД Oracle с установленной CHARSET=WE8ISO8859P1 по умолчанию. Иногда это делается по незнанию, чаще с мыслью, что эта инсталляция временна, никогда не поздно будет изменить; а некоторые версии, например, распространявшаяся через Интернет trial версия Personal Oracle for Windows 3.1, не имели локальных кодировок.
Когда при этом реально возникают проблемы:
К сожалению Oracle Corp. не предусмотрела легальных (документированных) способов изменения кодировок СУБД и приложений
Вопрос:Как можно решить проблемы, связанные с неверно заданной кодовой страницей?
- Изменение DATABASE CHARSET
Перекодировки данных здесь не происходит, изменяется только пометка для Oracle. Вы должны точно представлять в какой кодировке ваши данные находятся.
Прежде, чем использовать этот метод проверьте, присутствует ли необходимая вам кодировка в списке допустимых :
SQL> select value from V$NLS_VAL )
Текущие установки NLS БД можно просмотреть используя view NLS_DATABASE_PARAMETERS. Что представляет из себя это view?
SQL> select text from dba_views where view_name=’NLS_DATABASE_PARAMETERS’;
where name like ‘NLS%’
PROPS$ — это fixed table, где хранится информация об NLS и не только. Несмотря на термин fixed на многих версиях Oracle позволяет производить UPDATE над ней (хотя не во всех — какие-то версии Personal Oracle не допускают этого). Допустим Вы имеете WE8ISO8859P1, а Вам нужно CL8MSWIN1251.
SQL> select * from props$ where name=’NLS_CHARACTERSET’;
NAME VALUE$ COMMENT$
NLS_CHARACTERSET WE8ISO8859P1 Character set
SQL> update props$ set VALUE$=’CL8MSWIN1251′ where name=’NLS_CHARACTERSET’;
SQL> select * from props$ where name like ‘NLS_CHARACTERSET’;
NAME VALUE$ COMMENT$
NLS_CHARACTERSET CL8MSWIN1251 Character set
И после этого остается только поменять переменную среды NLS_LANG на сервере и клиентах и спокойно наслаждаться видом неизвращенных «Я» и «Ч» как больших так и маленьких.
Использование Export — Import
Как решить проблемы, возникающие при осуществлении экспорта в системе с кодировкой WE8ISO8859P1, а импорта на системе с русской кодировкой?
Использование параметра CHARSET применимо для импорта данных из версий ранее 7 (Oracle 5, 6). Экспортный файл версии 7 содержит в себе информацию о кодировке данных, из-за чего и возникают проблемы. Как же этого избежать?
Ответ заключается всего в одном байте экспортного файла, а именно — в третьем (точнее в двух байтах – втором и третьем, но в наших случаях второй байт равен 0x00), где и находится идентификатор CHARSET.
Кодировка | CS_ID(hex) | CS_ID(dec) | NLS RTL 3.1 Windows | NLS RTL 3.2 Windows | модуль из libnlsrtl.a * |
US7ASCII | 0x01 | 1 | lx20001.d | lx20001.nlb | lic001.o |
WE8ISO8859P1 | 0x1F | 31 | x2001F.d | lx2001F.nlb | lic031.o |
CL8ISO8859P5 | 0x23 | 35 | lx20023.d | lx20023.nlb | lic035.o |
RU8PC866 | 0x98 | 152 | lx20098.d | lx20098.nlb | lic152.o |
RU8BESTA | 0x99 | 153 | lx20099.d | lx20099.nlb | lic153.o |
RU8PC855 | 0x9B | 155 | lx2009B.d | lx2009B.nlb | lic155.o |
CL8MACCYRILLIC | 0x9E | 158 | lx2009E.d | lx2009E.nlb | lic158.o |
CL8MACCYRILLICS | 0x9F | 159 | lx2009F.d | lx2009F.nlb | lic159.o |
CL8MSWIN1251 | 0xAB | 171 | lx200AB.d | lx200AB.nlb | lic171.o |
CL8EBCDIC1025 | 0xB9 | 185 | lx200B9.d | lx200B9.nlb | lic185.o |
CL8EBCDIC1025X | 0xBA | 186 | lx200BA.d | lx200BA.nlb | |
CL8BS2000 | 0Xeb | 235 | lx200EB.d | lx200EB.nlb | lic235.o |
*- для Oracle 7.1.4 SCO Unix (в других версиях может отличаться)
Необходимо изменить этот байт с помощью любого шестнадцатеричного редактора.
Советы Игоря Филимонова ЛАСУ ТРИНИТИ, г. Троицк (Oracle Club)
Описанные методы применялись на версиях 7.1.4 — 7.2.2 для Windows 95, Windows NT, SCO Unix и.oracle 7.3 для HP/UX. Перед их использованием сделайте full export (backup).
За дополнительной информацией обращайтесь в компанию Interface Ltd.
На сегодняшний день использование набора символов Unicode стало стандартом в почти всём программном обеспечении. Вот уже несколько лет Oracle предлагает элегантное решение в виде кодировки AL32UTF8. Тем не менее, во многих случаях использование Unicode нежелательно, по причинам несовместимости со старыми версиями программных продуктов либо из соображений экономии дискового пространства, как в случае с бесплатным Oracle Express Edition.Данная заметка знакомит читателя с двумя подходами к использованию русского языка и сохранению кириллических символов в базах данных Oracle. Первый способ основан на «рекомендованном подходе» использования Юникод, что неизбежно влечёт за собой двойной перерасход места на диске. Второй способ считается устаревшим, но уменьшает обьём данных, используя строго один байт для каждого кириллического символа. Это особенно важно при использовании Oracle Express, где обьём данных физически ограничен всего одиннадцатью гигабайтами. Мы рассмотрим два варианта работы с русскими символами:
Но сначала остановимся на минутку и подумаем, какие программные компоненты участвуют в выводе русского символа из поля записи базы данных.»Внутри» базы, Оракл хранит символы в двоичном формате, в кодировке заданной при создании базы данных командой «CREATE DATABASE». Оракл должен знать что же за символ представлен тем или иным набором битов — иначе встроенные функции типа «upper», «lower» и «like» не смогут работать правильно.В нашем случае использования Linux, все начинается со взаимодействия со стандартной библиотекой C или C++. Оракл, как и другие программы, читает с диска несколько байт данных, преобразует их и отправляет в стандартный поток вывода один или несколько байт в некоей кодировке, как букву или цифру из определённого набора символов. Поскольку мы взаимодействуем с базой данных через клиента (предположим SQL*Plus), то приложение «sqlplus» отвечает за посылку данных в стандартный поток вывода и использует переменную окружения NLS_LANG для представления записей в правильном «выходном» формате.Linux, в свою очередь, принимает эти один или несколько байт, и выводит их на экран, по правилам текущей локали для оболочки пользователя, зависящих от переменной окружения LANG.Как видно, имеются три «параметра», определяющих что мы увидим на экране — правильную запись на русском языке или «крокозябли». А именно мы должны «объяснить» Ораклу и Линуксу на каком языке (в какой кодировке и какого набора символов) разговаривать с нами.Таким образом, для правильного вывода кириллицы из базы данных на экран мы должны установить эти переменные так, чтобы они совпали:
1 select * from nls_database_parameters
2* where parameter like ‘%CHARACTERSET’
15:14:49 SQL> /
PARAMETER VALUE
—————————— ————————-
NLS_CHARACTERSET AL32UTF8
NLS_NCHAR_CHARACTERSET AL16UTF16
Обратим внимание на значение параметра «NLS_CHARACTERSET» равное «AL32UTF8» (и проигнорируем «NLS_NCHAR_CHARACTERSET» — изучение этого параметра выходит за рамки нашей заметки. Также существует инициализационный параметр «NLS_LENGTH_SEMANTICS», который нужно устанавливать только на уровне сессии пользователя, но не для всего экземпляра оракла, обязательно прочтите про «NLS_LENGTH_SEMANTICS» в документации). Кодировка AL32UTF8 — это «ораклячая» версия UTF8 кодировки для набора символов Unicode. AL32UTF8 использует один байт для ASCII символов и до четырёх байт для всех остальных. Не используйте «ораклячую» UTF8 никогда — несмотря на совпадение имени, эта кодировка может занимать до шести байт для одного символа. Ещё раз — название кодировки «utf8» в Oracle — AL32UTF8.Проверим, какую кодировку будут использовать наш клиент (sqlplus) и оболочка Линукс (bash).
]$ env | grep LANG
NLS_LANG=English_America.AL32UTF8
LANG=en_US.utf8
[ora11@attack
]$ export LANG=ru_RU.utf8
[ora11@attack
Таким образом, первая часть значения переменной LANG определяет на каком языке (и для какой страны) с вами будет разговаривать Линукс, а вторая часть после точки задаёт кодировку набора символов.Как мы убедились, и Оракл и Линукс будут разговаривать с нами используя одну и ту же кодировку UTF8 и набор символов Unicode. Таков же и формат текстовых записей внутри базы данных (NLS_CHARACTERSET). Установку кодовой страницы терминала Гном проверим зайдя в меню «Terminal»-«Set Character Encoding». Должно быть отмечено значение «Unicode (UTF-8)»Проверим работу всей цепочки.
— Можно использовать «character semantics»:
— create table t (id number, msg varchar2(100 CHAR));
— В наших примерах мы используем «byte semantics».
15:45:10 SQL> create table t (id number, msg varchar2(100));
Elapsed: 00:00:00.37
15:45:42 SQL> insert into t values (1, ‘Тест 1’);
Elapsed: 00:00:00.01
15:46:02 SQL> insert into t values (2, ‘Проверка 2’);
Elapsed: 00:00:00.00
15:46:23 SQL> commit;
Elapsed: 00:00:00.02
15:46:25 SQL> col msg for a25
15:46:39 SQL> select * from t;
Elapsed: 00:00:00.01
15:46:44 SQL>
15:48:01 SQL> select * from t where msg like ‘Про%’;
Elapsed: 00:00:00.01
15:48:17 SQL> select * from t where upper (msg) = ‘ТЕСТ 1’;
Elapsed: 00:00:00.01
15:48:53 SQL> select lower(msg) from t;
Elapsed: 00:00:00.01
15:49:05 SQL>
Очевидно, что мы не только можем сохранить и вновь прочесть введённые записи, но и в состоянии правильно обработать их, используя встроенные функции Оракла. Что произойдёт, если мы изменим одно из значений в нашей «цепи»?
]$ env | grep LANG
NLS_LANG=English_America.AL32UTF8
LANG=ru_RU.koi8r
[ora11@attack
]$ env | grep LANG
NLS_LANG=English_America.CL8ISO8859P5
LANG=en_US.utf8
[ora11@attack
Если вы установите значение NLS_LANG в что-то несуществующее в представлении «v$NLS_VALID_VALUES», на экране возникнет ошибка «ORA-12705: Cannot access NLS data files or invalid environment specified». Но даже если одна из переменных окружения LANG или NLS_LANG будет установлена в правильное, но не совпадающее с базой данных (NLS_CHARACTERSET) значение — данные будет невозможно прочесть.Single byte — Данные сохраняются в КОИ-8Как сказано выше, сохранение русского текста в формате Юникод имеет нежелательный побочный эффект — объём данных удваивается. В большинстве случаев это не является проблемой и использование набора символов AL32UTF8 рекомендовано к использованию во всех базах данных Oracle.В то же время, я чётко вижу два сценария когда я бы предпочёл Юникоду какую-либо однобайтную кодировку, например КОИ-8. Во-первых, для очень большой базы с большим содержанием текстовой информации размером, скажем в 300Тб, разница в цене дисковой памяти между 600Тб и 300Тб слишком велика, чтобы пренебречь ею ради стандартизации. Во-вторых, при использовании Oracle XE, где максимальный размер хранимых данных ограничен производителем.В начале проверим, соответствует ли практика нашей теории.
— Вставляем русский текст в кодировке AL32UTF8, 2 байта на символ
declare i number;
begin
for i in 1..400 loop
insert into t values (i, ‘тестируем’);
end loop;
commit;
end;
/
16:29:48 SQL> /
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.07
16:29:49 SQL> select count(*) from t;
Elapsed: 00:00:00.00
16:29:56 SQL>
16:31:43 SQL> exec dbms_stats.gather_table_stats(‘SYS’, ‘T’);
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.97
16:31:53 SQL>
16:32:14 SQL> select NUM_ROWS, blocks, AVG_SPACE, AVG_ROW_LEN
16:32:55 2 from dba_tables
16:33:03 3 where table_name = ‘T’;
NUM_ROWS BLOCKS AVG_SPACE AVG_ROW_LEN
———- ———- ———- ————
400 3 0 41
Elapsed: 00:00:00.03
16:33:10 SQL>
16:33:10 SQL> truncate table t;
Elapsed: 00:00:00.12
16:34:51 SQL>
— Теперь тот же текст, но в ASCII одно-байтных символах
declare i number;
begin
for i in 1..400 loop
insert into t values (i, ‘testiruem’);
end loop;
commit;
end;
/
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.06
16:36:02 SQL> exec dbms_stats.gather_table_stats(‘SYS’, ‘T’);
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.10
16:36:20 SQL> select NUM_ROWS, blocks, AVG_SPACE, AVG_ROW_LEN
16:36:27 2 from dba_tables
16:36:30 3 where table_name = ‘T’;
NUM_ROWS BLOCKS AVG_SPACE AVG_ROW_LEN
———- ———- ———- ————
400 2 0 14
Elapsed: 00:00:00.00
16:36:33 SQL>
Мы видим почти 3-х кратную разницу в размере одной записи. Дополнительное место занимают внутренние служебные структуры базы данных. Таким образом, наша терория подтверждена практикой. И, поскольку мы используем Oracle XE, посмотрим как можно использовать кодировку КОИ-8 чтобы снизить объём данных и в то же время не потерять функциональность работы с русскими символами.
SQL*Plus: Release 11.2.0.2.0 Production on Wed Oct 12 16:56:09 2011
Copyright (c) 1982, 2011, Oracle. All rights reserved.
Enter user-name: / as sysdba
Connected to:
Oracle Database 11g Express Edition Release 11.2.0.2.0 — 64bit Production
16:56:18 SQL>
1 select * from nls_database_parameters
2* where parameter = ‘NLS_CHARACTERSET’
16:57:26 SQL> /
16:57:51 SQL>
16:57:51 SQL> create table t (id number, msg varchar2(100));
Elapsed: 00:00:00.39
16:58:47 SQL> insert into t values (1, ‘Тестируем русский в КОИ-8’);
Elapsed: 00:00:00.01
16:59:16 SQL> commit;
Elapsed: 00:00:00.02
16:59:18 SQL> select * from t;
Elapsed: 00:00:00.01
16:59:22 SQL>
Те же самые правила работают — кодировки всех «звеньев» в нашей цепи программных средств должны совпадать. База данных и клиент Оракла работают в кодировке «CL8KOI8R», локаль системы установлена в «koi8r» и эмулятор терминала использует кодовую страницу «Cyrillic (KOI8-R)». Удостоверимся, что использование одно-байтной кодировки позволяет нам существенно уменьшить размер записи.
declare i number;
begin
for i in 1..400 loop
insert into t values (i, ‘тестируем’);
end loop;
commit;
end;
/
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.06
17:10:54 SQL> exec dbms_stats.gather_table_stats(‘SYS’, ‘T’);
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.07
17:11:01 SQL> select NUM_ROWS, blocks, AVG_SPACE, AVG_ROW_LEN
17:11:06 2 from dba_tables
17:11:11 3 where table_name = ‘T’;
NUM_ROWS BLOCKS AVG_SPACE AVG_ROW_LEN
———- ———- ———- ————
400 2 0 14
Elapsed: 00:00:00.01
17:11:15 SQL> select * from t where rownum
В заключение надо отметить, что Оракл может конвертировать данные из одного набора симболов в другой «налету», такой эффект достигается установкой переменных окружения LANG и NLS_LANG в одно значение, соответствующее текущей локали операционной системы. В это же время NLS_CHARACTERSET «внутри» базы данных может отличаться от среды окружения пользователя — и в этом случае Оракл произведёт конвертирование данных, как показано ниже.
SQL*Plus: Release 11.2.0.2.0 Production on Чт Окт 13 12:03:37 2011
Copyright (c) 1982, 2010, Oracle. All rights reserved.
Введите имя пользователя: / as sysdba
Присоединен к:
Oracle Database 11g Release 11.2.0.2.0 — Production
12:03:40 SQL> select * from nls_database_parameters;
12:04:00 SQL> select * from t where rownum Отсоединено от Oracle Database 11g Release 11.2.0.2.0 — Production
[ora11@NAU
Как видно, работать с русскими символами в Оракле просто. Всё что необходимо — помнить о том, какую кодировку использует база данных и настраивать клиента, локаль и эмулятор терминала соответственно.Другие средства разработки также успешно будут работать с вашими данными — и в AL32UTF8, и в CL8KOI8R. В качестве упражнения я предлагаю читателю установить Oracle SQL Developer и проверить его работу с русским текстом в таблице «Т». Не забудьте проверить какую кодировку (и как) устанавливает для вас эта java-программа.
Может есть работающие алгоритмы смены кодировки?
1 ответ 1
Я так понял Вам надо изменить на уровне ДБ. Тогда надо в файле параметрах init.ora прописать NLS_LANGUAGE и NLS_TERRITORY отдельно.
NLS_LANG не используется в init.ora.
UPD Выше сказаное касалось языка и территории. Кодировкa устанавливается в NLS_CHARACTERSET, т.е. v 3-й составляющей NLS_LANG (languge_territory.characterset).
Кодировку можно изменить только, если новая кодировка является строгим супермножеством старой кодировки, т.е. нельзя поменять WE8ISO8859P5 на AL32UTF8, а US7ASCII можно всегда.
Использование Юникода в программах PL/SQL на примерах
До разработки стандарта Юникод существовало множество схем кодировки, которые обладали ограниченными возможностями, а порой и конфликтовали друг с другом. Разработка глобальных приложений по единым правилам была практически невозможна, потому что ни одна кодировка не поддерживала все символы.
Стандарт Юникод решает все эти проблемы. Он разрабатывается и сопровождается Консорциумом Юникода. Содержимое каждой версии определяется Стандартом Юникода и Базой данных символов Юникода, или USD (Unicode Character Database).
Набор символов Юникода позволяет хранить и извлекать данные в более чем 200 различных отдельных наборах. Использование набора символов Юникода обеспечивает поддержку всех этих наборов без внесения архитектурных изменений в приложение.
Рис. 1. Структура имени набора символов в Oracle
За дополнительной информацией о Юникоде обращайтесь на сайт Стандарта Юникод по адресу.
Типы данных и национальные наборы символов
Кодировка символов
Выбор набора символов во время создания базы данных определяет тип кодировки символов. Каждому символу ставится в соответствие код, уникальный для данного символа (кодовая точка). Это значение является частью таблицы отображения символов Юникода, содержимое которой находится под контролем Консорциума Юникода.
Кодовой единицей ( code unit ) называется размер в байтах типа данных, используемого для хранения символов. Размер кодовой единицы зависит от используемого набора символов. В некоторых обстоятельствах кодовая точка слишком велика для одной кодовой единицы, и для ее представления требуется несколько кодовых единиц.
Конечно, пользователи воспринимают символы, а не кодовые точки или кодовые единицы. «Слово» \0053\0074\0065\0076\0065\006E вряд ли будет понятно среднему пользователю, который распознает символы на своем родном языке. Не забывайте, что глиф (изображение символа, непосредственно отображаемое на экране) является всего лишь представлением кодового пункта. Даже если на вашем компьютере не установлены необходимые шрифты или он по другим причинам не может вывести символы на экран, это вовсе не означает, что в Oracle соответствующая кодовая точка хранится некорректно.
Параметры Globalization Support (NLS)
Таблица 1. Сеансовые параметры NLS
Функции юникода
Поддержка Юникода в PL/SQL начинается с простейших строковых функций. Впрочем, в табл. 2 видны небольшие отличия этих функций от их хорошо известных аналогов.
Таблица 2. Функции Юникода
Рассмотрим эти функции подробнее.
ASCIISTR
COMPOSE
Однако после использования функции COMPOSE эти две версии равны:
На этот раз сравнение дает другой результат:
DECOMPOSE
Как нетрудно догадаться, функция DECOMPOSE является обратной по отношению к COMPOSE : она разбивает составные символы на отдельные кодовые точки или элементы:
INSTR/INSTRB/INSTRC/INSTR2/INSTR4
LENGTH/LENGTHB/LENGTHC/LENGTH2/LENGTH4
Функции LENGTH возвращают длину строки в разных единицах:
LENGTH — возвращает длину строки в символах;
LENGTHB — возвращает длину строки в байтах;
LENGTHC — возвращает длину строки в символах Юникода;
LENGTH2 — возвращает количество кодовых единиц в строке;
LENGTH4 — возвращает количество кодовых точек в строке.
В данном примере только функция LENGTHB дает другой результат. Как и ожидалось, LENGTH и LENGTHC вернули одинаковые результаты. Впрочем, при работе с декомпозиционными символами ситуация меняется. Пример:
Функции возвращают следующие значения длины:
Функция LENGTH возвращает количество символов, но считает A и умляут разными символами. LENGTHC возвращает длину в символах Юникода и видит только один символ.
SUBSTR/SUBSTRB/SUBSTRC/SUBSTR2/SUBSTR4
SUBSTR — определяет позицию и длину по символу;
SUBSTRB — определяет позицию и длину в байтах;
SUBSTRC — определяет позицию и длину в символах Юникода;
SUBSTR2 — использует кодовые единицы;
SUBSTR4 — использует кодовые точки.
Использование этих функций продемонстрировано в следующем примере:
Обратите внимание на отличие SUBSTRB от других функций в результатах выполнения сценария:
UNISTR
Функция UNISTR преобразует строку в Юникод. Эта функция использовалась в ряде предыдущих примеров для вывода символов строки, подвергнутой декомпозиции. В разделе «Кодировка символов» в качестве примера была приведена строка, состоящая из кодовых пунктов. Чтобы привести ее к понятному виду, можно воспользоваться функцией UNISTR :