Переменные символьных типов предназначены для хранения текста, а для работы с ними используются символьные функции. Работа с символьными данными значительно различается по сложности от простой до весьма нетривиальной. В этой статье базовые средства PL/SQL по работе со строками рассматриваются в контексте однобайтовых наборов символов — например, тех, которые традиционно используются в Западной Европе и США. Если вы работаете в Юникоде или в другой многобайтовой кодировке или ваше приложение должно поддерживать несколько языков.
Хотя типы CLOB
(Character Large OBject) и LONG
теоретически тоже можно отнести к символьным типам, по принципам использования они отличаются от символьных типов, рассматриваемых в этой статье.
Строковые типы данных
Oracle поддерживает четыре строковых типа данных (табл. 1). Выбор типа зависит от двух факторов:
- Работаете ли вы со строками переменной или фиксированной длины?
- Хотите ли вы использовать набор символов базы данных или национальный набор символов?
Фиксированная длина | Переменная длина | |
Набор символов базы данных | CHAR | VARCHAR2 |
Национальный набор символов | NCHAR | NVARCHAR2 |
Типы данных фиксированной длины — CHAR
и NCHAR
— в приложениях Oracle используются очень редко. Их вообще не рекомендуется применять, если нет особых причин работать именно со строкой фиксированной длины. Далее, в разделе «Смешение значений CHAR
и VARCHAR2
» рассказывается о проблемах, которые могут возникнуть при совместном использовании строковых переменных фиксированной и переменной длины.
Тип данных VARCHAR2
В переменных типа VARCHAR2
хранятся символьные строки переменной длины. При объявлении такой строки для нее определяется максимальная длина в диапазоне от 1 до 32 767 байт. Максимальная длина может задаваться в байтах или символах, но в любом случае компилятор определяет ее в байтах. Общий синтаксис объявления VARCHAR2
:
имя_переменной VARCHAR2 (макс_длина [CHAR | BYTE]);
Здесь имя_переменной — имя объявляемой переменной, макс_длина
— ее максимальная длина, а CHAR
и BYTE
— аргументы, указывающие, что максимальная длина выражается в символах или в байтах соответственно.
Если максимальная длина строковой переменной VARCHAR2
задается в символах (спецификатор CHAR
), то ее реальная длина в байтах вычисляется на основе максимального количества байтов, используемых для представления одного символа. Например, набор символов Юникода UTF-8 использует для представления некоторых символов до 4 байтов; следовательно, если вы работаете с UTF-8, объявление переменной типа VARCHAR2
, максимальная длина которой составляет 100 символов, эквивалентно объявлению этой же переменной с максимальной длиной 300 байт.
Спецификатор длины CHAR
используется в основном при работе с многобайтовыми наборами символов — такими, как UTF-8.
Если в объявлении переменной VARCHAR2
опустить спецификатор CHAR
или BYTE
, тогда заданное значение длины будет интерпретировано в байтах или символах в зависимости от параметра инициализации NLS_LENGTH_SEMANTICS
. Текущее значение можно узнать, обратившись с запросом к NLS_SESSION_PARAMETERS
. Несколько примеров объявления строк типа VARCHAR2
:
DECLARE small_string VARCHAR2(4); line_of_text VARCHAR2(2000); feature_name VARCHAR2(100 BYTE); -- Строка длиной 100 байт emp_name VARCHAR2(30 CHAR); ------- Строка длиной 30 символов
Итак, максимальная длина переменной типа VARCHAR2
в PL/SQL составляет 32 767 байт. Это ограничение действует независимо от того, определяется ли длина строки в байтах или символах. До выхода версии 12c максимальная длина типа данных VARCHAR2
в SQL была равна 4000; в 12c она была увеличена до максимума PL/SQL: 32 767 байт. Однако следует учитывать, что SQL поддерживает этот максимум только в том случае, если параметру инициализации MAX_SQL_STRING_SIZE
задано значение EXTENDED
; по умолчанию используется значение STANDARD
.
Если вам понадобится работать со строками длиной более 4000 байт, рассмотрите возможность их хранения в столбцах типа CLOB
.
Тип данных CHAR
Тип данных CHAR
определяет строку фиксированной длины. При объявлении такой строки необходимо задать ее максимальную длину в диапазоне от 1 до 32 767 байт. Длина может задаваться как в байтах, так и в символах. Например, следующие два объявления создают строки длиной 100 байт и 100 символов соответственно:
feature_name CHAR(100 BYTE); feature_name CHAR(100 CHAR);
Реальный размер 100-символьной строки в байтах зависит от текущего набора символов базы данных. Если используется набор символов с переменной длиной кодировки, PL/SQL выделяет для строки столько места, сколько необходимо для представления заданного количества символов с максимальным количеством байтов. Например, в наборе UTF-8, где символы имеют длину от 1 до 4 байт, PL/SQL при создании строки для хранения 100 символов зарезервирует 300 байт (3 байта ? 100 символов).
Мы уже знаем, что при отсутствии спецификатора CHAR
или BYTE
результат будет зависеть от параметра NLS_LENGTH_SEMANTICS
. При компиляции программы эта настройка сохраняется вместе с ней и может использоваться повторно или заменяться при последующей перекомпиляции. С настройкой по умолчанию для следующего объявления будет создана строка длиной 100 байт:
feature_name CHAR(100);
Если длина строки не указана, PL/SQL объявит строку длиной 1 байт. Предположим, переменная объявляется так:
feature_name CHAR;
Как только этой переменной присваивается строка длиной более одного символа, PL/SQL инициирует универсальное исключение VALUE_ERROR
. Но при этом не указывается, где именно возникла проблема. Если эта ошибка была получена при объявлении новых переменных или констант, проверьте свои объявления на небрежное использование CHAR
. Чтобы избежать проблем и облегчить работу программистов, которые придут вам на смену, всегда указывайте длину строки типа CHAR
. Несколько примеров:
yes_or_no CHAR (1) DEFAULT 'Y'; line_of_text CHAR (80 CHAR); ----- Всегда все 80 символов! whole_paragraph CHAR (10000 BYTE); -- Подумайте обо всех этих пробелах...
Поскольку строка типа CHAR
имеет фиксированную длину, PL/SQL при необходимости дополняет справа присвоенное значение пробелами, чтобы фактическая длина соответствовала максимальной, указанной в объявлении.
До выхода версии 12c максимальная длина типа данных CHAR
в SQL была равна 2000; в 12c она была увеличена до максимума PL/SQL: 32 767 байт. Однако следует учитывать, что SQL поддерживает этот максимум только в том случае, если параметру инициализации MAX_SQL_STRING_SIZE
задано значение EXTENDED
.
Строковые подтипы
PL/SQL поддерживает некоторые строковые подтипы (табл. 2), которые тоже могут использоваться для объявления символьных строк. Многие из этих подтипов определены только для обеспечения совместимости со стандартом ANSI SQL. Вряд ли они вам когда-нибудь понадобятся, но знать о них все же нужно.
Каждый из перечисленных в таблице подтипов эквивалентен одному из базовых типов данных PL/SQL, указанных в правом столбце. Например:
feature_name VARCHAR2(100); feature_name CHARACTER VARYING(100); feature_name CHAR VARYING(100); feature_name STRING(100);
Подтип VARCHAR
заслуживает особого внимания. Уже на протяжении нескольких лет корпорация Oracle собирается изменить определение подтипа данных VARCHAR
(в результате чего он перестанет быть эквивалентным VARCHAR2
) и предупреждает, что пользоваться им не следует. Я согласен с этой рекомендацией: если существует опасность, что Oracle (или комитет ANSI) изменит поведение VARCHAR
, неразумно полагаться на его поведение. Используйте вместо него VARCHAR2
.
Подтип | Эквивалентный тип |
CHAR VARYING | VARCHAR2 |
CHARACTER | CHAR |
CHARACTER VARYING | VARCHAR2 |
NATIONAL CHAR | NCHAR |
NATIONAL CHAR VARYING | NVARCHAR2 |
NATIONAL CHARACTER | NCHAR |
NATIONAL CHARACTER VARYING | NVARCHAR2 |
NCHAR VARYING | NVARCHAR2 |
STRING | VARCHAR2 |
VARCHAR | VARCHAR2 |