FAQ по ORACLE. Проблемы кодировки.

How do i check the nls_lang of the client?

This is what I do when I troubleshoot encoding-issues. (The NLS_LANG value read by sqlplus):

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

You will have to extract the NLS_LANG value in current ORACLE_HOME from the registry.
All client-side tools (sqlplus, sqlldr, exp, imp, oci, etc…) read this value from registry
and determine if any character transcoding should occur.

ORACLE_HOME and registry section:

C:>dir /s/b oracle.key
C:Oracle10BINoracle.key

C:>type C:Oracle10BINoracle.key
SOFTWAREORACLEKEY_OraClient10204_Home

In times like these I turn to IPython to demonstrate an idea:

A couple of lookups and you are there!

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_Homen'

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)

Вопрос:как можно решить проблемы, связанные с неверно заданной кодовой страницей?

Ответ:

  1. Изменение DATABASE CHARSET

    Перекодировки данных здесь не происходит, изменяется только пометка
    для Oracle. Вы должны точно представлять в какой кодировке ваши данные
    находятся.

    Прежде, чем использовать этот метод проверьте, присутствует ли необходимая
    вам кодировка в списке допустимых :

    SQL> select value from V$NLS_VALID_VALUES

  2. where parameter=’CHARACTERSET’
  3. and (value like ‘RU%’ or value like ‘CL%’)

    VALUE


    CL8ISO8859P5

    RU8PC866

    RU8BESTA

    RU8PC855

    CL8MACCYRILLIC

    CL8MACCYRILLICS

    CL8MSWIN1251

    CL8EBCDIC1025

    CL8EBCDIC1025X

    CL8BS2000

    Текущие установки NLS БД можно просмотреть используя view NLS_DATABASE_PARAMETERS.
    Что представляет из себя это view?

    SQL> select text from dba_views where view_name=’NLS_DATABASE_PARAMETERS’;

    TEXT


    select name,

    substr(value$, 1, 30)

    from props$

    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’;

    1. row updated.

      SQL> select * from props$ where name like ‘NLS_CHARACTERSET’;

      NAME VALUE$ COMMENT$


      NLS_CHARACTERSET CL8MSWIN1251 Character set

      SQL> commit;

      Commit complete.

      И после этого остается только поменять переменную среды NLS_LANG на
      сервере и клиентах и спокойно наслаждаться видом неизвращенных “Я” и “Ч”
      как больших так и маленьких.

    2. Использование Export – Import

      Как решить проблемы, возникающие при осуществлении экспорта в системе
      с кодировкой WE8ISO8859P1, а импорта на системе с русской кодировкой?

      Использование параметра CHARSET применимо для импорта данных из версий
      ранее 7 (Oracle 5, 6). Экспортный файл версии 7 содержит в себе информацию
      о кодировке данных, из-за чего и возникают проблемы. Как же этого избежать?

      Ответ заключается всего в одном байте экспортного файла, а именно –
      в третьем (точнее в двух байтах – втором и третьем, но в наших случаях
      второй байт равен 0x00), где и находится идентификатор CHARSET.

      Таблица . Идентификаторы CHARSET.

      КодировкаCS_ID(hex) CS_ID(dec)NLS RTL 3.1 WindowsNLS RTL 3.2 Windowsмодуль из libnlsrtl.a *
      US7ASCII0x011lx20001.dlx20001.nlblic001.o
      WE8ISO8859P1 0x1F31x2001F.dlx2001F.nlblic031.o
      CL8ISO8859P5 0x23 35lx20023.dlx20023.nlblic035.o
      RU8PC866 0x98 152 lx20098.d lx20098.nlb lic152.o
      RU8BESTA0x99 153 lx20099.dlx20099.nlblic153.o 
      RU8PC855 0x9B155lx2009B.d lx2009B.nlblic155.o 
      CL8MACCYRILLIC 0x9E 158lx2009E.dlx2009E.nlblic158.o 
      CL8MACCYRILLICS 0x9F159 lx2009F.dlx2009F.nlblic159.o
      CL8MSWIN1251 0xAB 171 lx200AB.dlx200AB.nlblic171.o 
      CL8EBCDIC1025 0xB9 185lx200B9.dlx200B9.nlblic185.o 
      CL8EBCDIC1025X 0xBA 186 lx200BA.dlx200BA.nlb 
      CL8BS2000 0Xeb235 lx200EB.dlx200EB.nlblic235.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).

Вопрос:как правильно выбрать кодовую страницу при инсталляции?

Ответ: Cпособы корректной установки поддержки национальных кодировок и стандартов
в продуктах Oraclе обсуждались в статье С. Мосина [Oracle Magazine/Russian Edition
номер 1 за лето 1996]

При инсталляции необходимо выбирать “Русский”, даже если это пробная
установка.

Однако часто еще встречаются СУБД Oracle с установленной CHARSET=WE8ISO8859P1
по умолчанию. Иногда это делается по незнанию, чаще с мыслью, что эта инсталляция
временна, никогда не поздно будет изменить; а некоторые версии, например,
распространявшаяся через Интернет trial версия Personal Oracle for Windows
3.1, не имели локальных кодировок.

Когда при этом реально возникают проблемы:

  • когда система переносится на платформу с другой основной кодировкой,
  • когда необходимо реэкспортировать в такую систему несколько таблиц с другой
    кодировкой,
  • неудобства типа невозможности перевода в другой регистр русских ‘Ч’ и ‘Я’
    (временно можно корректировать написанием локализованных версий функций
    RLOWER() и RUPPER()).
:/>  Программа для безопасного извлечения флешки

К сожалению Oracle Corp. не предусмотрела легальных (документированных)
способов изменения кодировок СУБД и приложений

Кодировка символов

Выбор набора символов во время создания базы данных определяет тип кодировки символов. Каждому символу ставится в соответствие код, уникальный для данного символа (кодовая точка). Это значение является частью таблицы отображения символов Юникода, содержимое которой находится под контролем Консорциума Юникода.

Кодовые точки состоят из префикса U (или обратной косой черты ), за которым следует шестнадцатеричный код символа с диапазоном допустимых значений от U 0000 до U 10FFFF16. Комбинированные символы (например, А) могут разбиваться на компоненты (A с умляутом), а затем снова восстанавливаться в своем исходном состоянии.

Кодовой единицей (code unit) называется размер в байтах типа данных, используемого для хранения символов. Размер кодовой единицы зависит от используемого набора символов. В некоторых обстоятельствах кодовая точка слишком велика для одной кодовой единицы, и для ее представления требуется несколько кодовых единиц.

Конечно, пользователи воспринимают символы, а не кодовые точки или кодовые единицы. «Слово» 05307406507606506E вряд ли будет понятно среднему пользователю, который распознает символы на своем родном языке. Не забывайте, что глиф (изображение символа, непосредственно отображаемое на экране) является всего лишь представлением кодового пункта.

Параметры globalization support (nls)

Поведение Oracle по умолчанию определяется параметрами Globalization Support (NLS). Значения параметров, задаваемые при создании базы данных, определяют многие аспекты ее работы — от наборов символов до используемых по умолчанию денежных единиц. В табл.

Таблица 1. Сеансовые параметры NLS

ПараметрОписаниеПример
NLS_CALENDARЗадает календарь по умолчанию для базы данных GREGORIAN
 NLS_COMP В сочетании с NLS_SORT определяет правила сортировки символов. При использовании значения ANSI необходимо использовать лингвистический индекс BINARY
 NLS_CURRENCYЗадает знак денежной единицы; по умолчанию
определяется на основании NLS_TERRITORY
 $
 NLS_DATE_FORMAT Задает формат даты; по умолчанию определяется
на основании NLS_TERRITORY
 DD-MON-RR
 NLS_DATE_LANGUAGE Определяет способ записи дня и месяца для функций обработки дат AMERICAN
 NLS_DUAL_CURRENCY Упрощает поддержку евро; по умолчанию определяется на основании NLS_TERRITORY. Задает альтернативную денежную единицу для территории $
 NLS_ISO_CURRENCY Символ денежной единицы ISO; по умолчанию
определяется на основании NLS_TERRITORY
 AMERICA
 NLS_LANGUAGE Задает язык, используемый базой данных по умолчанию. Значение влияет на многие аспекты, от формата даты до сообщений сервера AMERICAN
NLS_LENGTH_SEMANTICSОпределяет используемую семантику длины (символы или байты)BYTE
NLS_NCHAR_CONV_EXCPОпределяет, должно ли выдаваться сообщение об ошибке при преобразовании символьного типаFALSE
NLS_NUMERIC_CHARACTERSОпределяет разделители дробной части и групп
разрядов; по умолчанию определяется на основании NLS_TERRITORY
.,
NLS_SORTОпределяет порядок сортировки символов для заданного языкаBINARY
NLS_TERRITORYОпределяет значения по умолчанию многих параметров NLS. Значение определяет основной регион базы данныхAMERICA
NLS_TIMESTAMP_FORMATОпределяет формат временной метки по умолчанию для функций TO_TIMESTAMP и TO_CHARDD-MON-RR HH.MI.SSXF F AM
NLS_TIMESTAMP_TZ_FORMATОпределяет формат временной метки с часовым
поясом для функций TO_TIMESTAMP и TO_CHAR
DD-MON-RR HH.MI.SSXF F AM TZR
NLS_TIME_FORMATИспользуется в сочетании с NLS_DATE_FORMAT
(см. выше). Задает формат времени по умолчанию
для базы данных
HH.MI.SSXF F AM
NLS_TIME_TZ_FORMATОпределяет формат времени с часовым поясом или
смещением UTC
HH.MI.SSXF F AM TZR

Проблема с кодировкой русского языка при отправке на сервер – pl/sql (post)

Коллеги! На выходе при получении сервером xml посредством процедуры ниже русский шрифт “ЗАПИСЬ ДОБАВЛЕНА ИЗ ПРЕДВАРИТЕЛЬНОГО ПОИСКА” заменяется на:

“???????????? ?????`???????????? ???? ???????????????????????????????? ????????????”

Кодировка Оракла windows-1251, однако convert(misc, ‘UTF8’) не помогает.

XML:

<?xml version="1.0"?>
<record>
  <ROW>
  <LASTNAME>PETROSYAN</LASTNAME>
  <MISC>ЗАПИСЬ ДОБАВЛЕНА ИЗ ПРЕДВАРИТЕЛЬНОГО ПОИСКА</MISC>
 </ROW>
</record>
procedure afl_to_akr(l_result in CLOB) is
  req   utl_http.req;
  res   utl_http.resp;
  l_out VARCHAR2(32767);
  l_url varchar2(690) := l_url := 'http://10.120.48.3:8180/ab-int/integroServlet';
  l_body CLOB;
begin
   req := utl_http.begin_request(l_url, 'POST', 'HTTP/1.1');
   utl_http.set_header(req, 'Content-Type', 'application/x-www-form-urlencoded'); 
   l_body := 'xml=' || l_result;      
   utl_http.set_header(req, 'Content-Length', length(l_body));
   utl_http.write_text(req, l_body);
   res := utl_http.get_response(req);
   begin
      utl_http.read_line(res, l_out);
      utl_http.end_response(res);
   exception
      when utl_http.end_of_body then
         utl_http.end_response(res);
   end;  
end;

Проблемы кодировки

  • Как получить в Oracle список всех первичных ключей в виде:
    [id_column], [id_table]?
  • Как правильно выбрать кодовую страницу
    при инсталляции?
  • Как
    можно решить проблемы, связанные с неверно заданной кодовой страницей?
  • Решение проблемы: кракозябры в pl/sql developer (кодировка, oracle) /

    Ошибка в вашей настройке языка. Клиент Oracle берет настройку языка из виндовой переменной NLS_LANG, если я правильно помню, ее нужно установить в значение RUSSIAN_AMERICA.CL8MSWIN1251.

    Сделать в Винде это можно в “Свойствах системы”, закладка “Дополнительно”, кнопка “Переменные среды”. Добавляете этот параметр, если он не создался клиентом Oracle и задаете значение.

    :/>  Скачать W10Privacy на русском - блокировщик служб Windows 10.

    Типы данных и национальные наборы символов

    Типы данных Globalization Support nclob, nchar и nvarchar2 используют набор сим­волов, определяемый параметром nls_nchar_characterset, — вместо набора символов по умолчанию, устанавливаемого для базы данных в параметре nls_characterset.

    Эти типы данных поддерживают только многобайтовые символы Юникода, поэтому даже при работе с базой данных, в которой по умолчанию вместо Юникода используется другая кодировка, они будут хранить символы в национальном наборе символов. А так как национальный набор символов поддерживает только кодировки UTF-8 и UTF- 16, NCLOB, NCHAR и NVARCHAR2 гарантированно будут хранить данные в многобайтовом Юникоде.

    Прежде это создавало проблемы при сравнении столбцов nclob/nchar/nvarchar2 со столбцами clob/char/varchar2. Во всех версиях, поддерживаемых в настоящее время, Oracle выполняет автоматическое преобразование, благодаря которому становится возможным корректное сравнение.

    Функции юникода

    Поддержка Юникода в PL/SQL начинается с простейших строковых функций. Впрочем, в табл. 2 видны небольшие отличия этих функций от их хорошо известных аналогов.

    К именам функций INSTR, LENGTH и SUBSTR добавляется суффикс B, C, 2 или 4; он озна­чает, что функция работает с байтами, символами, кодовыми единицами или кодовыми точками соответственно.

    Функции INSTR, LENGTH и SUBSTR используют семантику длины, связанную с типом данных столбца или переменной. Эти базовые функции и версии с суф­фиксом C часто возвращают одинаковые значения — до тех пор, пока вы не начнете работать со значениями NCHAR или NVARCHAR.

    Поскольку NLS_NCHAR_ CHARACTERSET и NLS_CHARACTERSET могут различаться, результат вызова INSTR, LENGTH и SUBSTR может отличаться (в зависимости от типа данных) от результата их символьных аналогов.

    Таблица 2. Функции Юникода

    Функция ЮникодаОписание
    ASCIISTR(string)Преобразует строку string в ASCn-символы. Строки в Юникоде преобразуются в стандартный формат xxxx
    COMPOSE(string)Преобразует строку string, полученную в результате декомпозиции, в полную композиционную форму
    DECOMPOSE(string, [canonical | compatibility])Получает строку string и возвращает строку Юникода, полученную разложением составных символов на кодовые
    INSTRB(string, substr, pos, occ)Возвращает позицию подстроки substr в строке string в байтах, на­чиная с позиции pos. Аргумент occ задает номер вхождения substr, если подстрока встречается более одного раза. По умолчанию аргументы pos и occ
    INSTRC(string, substr, pos, occ)Аналог INSTRB — за исключением того, что возвращает позицию substr в string в символах, начиная с позиции pos (значение pos задается в символах)
    INSTR2(string, substr, pos, occ)Возвращаемая позиция задается в кодовых единицах UTF-16
    INSTR4(string, substr, pos, occ)Возвращаемая позиция задается в кодовых точках UTF-16
    LENGTHB(string)Возвращает размер строки string в байтах
    LENGTHC(string)Возвращает длину строки string в символах Юникода
    LENGTH2(string)Возвращаемая длина задается в кодовых единицах UTF-16
    LENGTH4(string)Возвращаемая длина задается в кодовых точках UTF-16
    SUBSTRB(string, n, m)Возвращает часть строки string, состоящую из m символов, начиная
    с позиции n. Значения n и m задаются в байтах
    SUBSTRC(string, n, m)Возвращает часть строки string, состоящую из m символов, начиная
    с позиции n. Значения n и m задаются в символах Юникода
    SUBSTR2(string, n, m)Значения n и m задаются в кодовых единицах UTF-16
    SUBSTR4(string, n, m)Значения n и m задаются в кодовых точках UTF-16
    UNISTRПреобразует представление строки string из ASCII-формата (обрат-
    ная косая черта, шестнадцатеричные цифры) в Юникод

    Рассмотрим эти функции подробнее.

    ASCIISTR

    ASCIISTR пытается преобразовать полученную строку в ASCII-символы. Если строка содержит символы, отсутствующие в наборе ASCII, они представляются в формате xxxx. Как будет показано ниже при описании функции DECOMPOSE, такое форматирование иногда оказывается очень удобным.

    BEGIN
       DBMS_OUTPUT.put_line ('ASCII Character: ' || ASCIISTR ('A'));
       DBMS_OUTPUT.put_line ('Unicode Character: ' || ASCIISTR ('Ä'));
    END;

    Результат:

    ASCII Character: A
    Unicode Character: 0C4

    COMPOSE

    Некоторые символы могут иметь несколько вариантов представления кодовых пун­ктов. Это создает проблемы при сравнении двух значений. Символ А может быть представлен как одним кодовым пунктом U 00C4, так и двумя кодовыми пунктами U 0041 (буква A) и U 0308. При сравнении PL/SQL считает, что эти два варианта представления не равны.

    DECLARE
       v_precomposed   VARCHAR2 (20) := UNISTR ('0C4');
       v_decomposed    VARCHAR2 (20) := UNISTR ('A308');
    BEGIN
       IF v_precomposed = v_decomposed
       THEN
          DBMS_OUTPUT.put_line ('==EQUAL==');
       ELSE
          DBMS_OUTPUT.put_line ('<>NOT EQUAL<>');
       END IF;
    END;

    Результат:

    Однако после использования функции COMPOSE эти две версии равны:

    DECLARE
       v_precomposed   VARCHAR2 (20) := UNISTR ('0C4');
       v_decomposed    VARCHAR2 (20) := COMPOSE (UNISTR ('A308'));
    BEGIN
       IF v_precomposed = v_decomposed
       THEN
          DBMS_OUTPUT.put_line ('==EQUAL==');
       ELSE
          DBMS_OUTPUT.put_line ('<>NOT EQUAL<>');
       END IF;
    END;

    На этот раз сравнение дает другой результат:

    ==EQUAL==

    DECOMPOSE

    Как нетрудно догадаться, функция DECOMPOSE является обратной по отношению к COMPOSE: она разбивает составные символы на отдельные кодовые точки или элементы:

    DECLARE
       v_precomposed   VARCHAR2 (20) := ASCIISTR (DECOMPOSE ('Ä'));
       v_decomposed    VARCHAR2 (20) := 'A308';
    BEGIN
       IF v_precomposed = v_decomposed
       THEN
          DBMS_OUTPUT.put_line ('==EQUAL==');
       ELSE
          DBMS_OUTPUT.put_line ('<>NOT EQUAL<>');
       END IF;
    END;

    Результат:

    ==EQUAL==

    INSTR/INSTRB/INSTRC/INSTR2/INSTR4

    :/>  Firefox 98.0.1 перестал поддерживать Яндекс и в качестве поисковиков по умолчанию

    Все функции INSTR возвращают позицию подстроки внутри строки и различаются лишь по способу определения позиции. Для демонстрации мы воспользуемся таблицей publication из схемы g11n.

    DECLARE
       v_instr    NUMBER (2);
       v_instrb   NUMBER (2);
       v_instrc   NUMBER (2);
       v_instr2   NUMBER (2);
       v_instr4   NUMBER (2);
    BEGIN
       SELECT INSTR (title, 'グ'),
     INSTRB (title, 'グ'),
     INSTRC (title, 'グ
    '),
     INSTR2 (title, 'グ'),
     INSTR4 (title, 'グ
    ')
         INTO v_instr, v_instrb, v_instrc,
              v_instr2, v_instr4
         FROM publication
        WHERE publication_id = 2;
    
       DBMS_OUTPUT.put_line ('INSTR of グ: ' || v_instr);
       DBMS_OUTPUT.put_line ('INSTRB of グ: ' || v_instrb);
       DBMS_OUTPUT.put_line ('INSTRC of グ: ' || v_instrc);
       DBMS_OUTPUT.put_line ('INSTR2 of グ: ' || v_instr2);
       DBMS_OUTPUT.put_line ('INSTR4 of グ: ' || v_instr4);
    END;
    /

    Результат:

    INSTR of グ: 16
    INSTRB of グ: 20
    INSTRC of グ: 16
    INSTR2 of グ: 16
    INSTR4 of グ: 16

    Позиция символа У отличается только для INSTRB. Одна из полезных особенностей INSTR2 и INSTR4 заключается в том, что они могут использоваться для поиска кодовых точек, не представляющих полные символы. Возвращаясь к примеру с символом А, умляут можно включить как подстроку для выполнения поиска.

    LENGTH/LENGTHB/LENGTHC/LENGTH2/LENGTH4

    Функции LENGTH возвращают длину строки в разных единицах:

    LENGTH — возвращает длину строки в символах;

    LENGTHB — возвращает длину строки в байтах;

    LENGTHC — возвращает длину строки в символах Юникода;

    LENGTH2 — возвращает количество кодовых единиц в строке;

    LENGTH4 — возвращает количество кодовых точек в строке.

    Если строка состоит из композиционных символов, функция LENGTH эквивалентна LENGTHC.

    DECLARE
       v_length    NUMBER (2);
       v_lengthb   NUMBER (2);
       v_lengthc   NUMBER (2);
       v_length2   NUMBER (2);
       v_length4   NUMBER (2);
    BEGIN
       SELECT LENGTH (title), LENGTHB (title), lengthc (title), length2 (title),
              length4 (title)
         INTO v_length, v_lengthb, v_lengthc, v_length2,
              v_length4
         FROM publication
        WHERE publication_id = 2;
    
       DBMS_OUTPUT.put_line ('LENGTH of string: ' || v_length);
       DBMS_OUTPUT.put_line ('LENGTHB of string: ' || v_lengthb);
       DBMS_OUTPUT.put_line ('LENGTHC of string: ' || v_lengthc);
       DBMS_OUTPUT.put_line ('LENGTH2 of string: ' || v_length2);
       DBMS_OUTPUT.put_line ('LENGTH4 of string: ' || v_length4);
    END;

    Результат:

    LENGTH of string: 28
    LENGTHB of string: 52
    LENGTHC of string: 28
    LENGTH2 of string: 28
    LENGTH4 of string: 28

    В данном примере только функция LENGTHB дает другой результат. Как и ожидалось, LENGTH и LENGTHC вернули одинаковые результаты. Впрочем, при работе с декомпозицион­ными символами ситуация меняется. Пример:

    DECLARE
       v_length   NUMBER (2);
    BEGIN
       SELECT LENGTH (UNISTR ('A308'))
         INTO v_length
         FROM DUAL;
    
       DBMS_OUTPUT.put_line ('Decomposed string size using LENGTH: ' || v_length);
    
       SELECT lengthc (UNISTR ('A308'))
         INTO v_length
         FROM DUAL;
    
       DBMS_OUTPUT.put_line ('Decomposed string size using LENGTHC: ' || v_length);
    END;

    Функции возвращают следующие значения длины:

    Decomposed string size using LENGTH: 2
    Decomposed string size using LENGTHC: 1

    Функция LENGTH возвращает количество символов, но считает A и умляут разными символами. LENGTHC возвращает длину в символах Юникода и видит только один символ.

    SUBSTR/SUBSTRB/SUBSTRC/SUBSTR2/SUBSTR4

    Разные версии SUBSTR определяются по тому же принципу, что и их аналоги у функций INSTR с LENGTH. SUBSTR возвращает часть строки заданной длины начиная с заданной позиции. Функции этого семейства работают следующим образом:

    SUBSTR — определяет позицию и длину по символу;

    SUBSTRB — определяет позицию и длину в байтах;

    SUBSTRC — определяет позицию и длину в символах Юникода;

    SUBSTR2 — использует кодовые единицы;

    SUBSTR4 — использует кодовые точки.

    Использование этих функций продемонстрировано в следующем примере:

    DECLARE
       v_substr    VARCHAR2 (20);
       v_substrb   VARCHAR2 (20);
       v_substrc   VARCHAR2 (20);
       v_substr2   VARCHAR2 (20);
       v_substr4   VARCHAR2 (20);
    BEGIN
       SELECT SUBSTR (title, 13, 4), SUBSTRB (title, 13, 4),
              substrc (title, 13, 4), substr2 (title, 13, 4),
              substr4 (title, 13, 4)
         INTO v_substr, v_substrb,
              v_substrc, v_substr2,
              v_substr4
         FROM publication
        WHERE publication_id = 2;
    
       DBMS_OUTPUT.put_line ('SUBSTR of string: ' || v_substr);
       DBMS_OUTPUT.put_line ('SUBSTRB of string: ' || v_substrb);
       DBMS_OUTPUT.put_line ('SUBSTRC of string: ' || v_substrc);
       DBMS_OUTPUT.put_line ('SUBSTR2 of string: ' || v_substr2);
       DBMS_OUTPUT.put_line ('SUBSTR4 of string: ' || v_substr4);
    END;

    Обратите внимание на отличие SUBSTRB от других функций в результатах выполнения сценария:

    SUBSTR of string: Lプログ
    SUBSTRB of string: Lプ
    SUBSTRC of string: Lプログ
    SUBSTR2 of string: Lプログ
    SUBSTR4 of string: Lプログ

    UNISTR

    Функция UNISTR преобразует строку в Юникод. Эта функция использовалась в ряде предыдущих примеров для вывода символов строки, подвергнутой декомпозиции. В разделе «Кодировка символов» в качестве примера была приведена строка, состоя­щая из кодовых пунктов. Чтобы привести ее к понятному виду, можно воспользоваться функцией UNISTR:

    DECLARE
       v_string   VARCHAR2 (20);
    BEGIN
       SELECT UNISTR ('05307406507606506E')
         INTO v_string
         FROM DUAL;
    
       DBMS_OUTPUT.put_line (v_string);
    END;

    Результат:

    Steven

    Оставьте комментарий