Основы языка PL/SQL: литералы

Что такое литералы языка PL/SQL Oracle и как их использоватьЛитералом (literal) называется значение, с которым не связан идентификатор; оно существует «само по себе». Несколько примеров литералов, которые могут встретиться в программе PL/SQL:

  • Числа:
     415, 21.6, 3.141592654f, 7D, NULL
  • Строки:
     'This is my sentence', '01-OCT-1986', q'!hello!', NULL 
  • Временные интервалы:
     INTERVAL '25-6' YEAR TO MONTH, INTERVAL '-18' MONTH, NULL 
  • Логические значения:
     TRUE, FALSE, NULL 

Суффикс «f» в числовом литерале 3.14159f обозначает 32-разрядное вещественное число в стандарте IEEE 754, частично поддерживаемом Oracle, начиная с версии 10g Release 1. Аналогичным образом, 7D — число 7, представленное в 64-разрядном вещественном формате.

О строке q'!hello!' следует упомянуть особо. Знак ! — пользовательский ограничитель (возможность использования пользовательских ограничителей также появилась в Oracle10g). Начальная буква q и одинарные кавычки, в которые заключено значение, сообщают компилятору, что ! — ограничитель, а не часть значения, а строка содержит просто слово hello.

Тип данных INTERVAL предназначен для работы с интервалами между определенными датами или моментами времени. Первый интервал в приведенном выше примере означает «через 25 лет и еще 6 месяцев», а второй — «на 18 месяцев ранее».

Хотя интервалы могут задаваться в литеральном формате, для типов DATE такая возможность не предусмотрена; скажем, значение '01-OCT-1986' интерпретируется как строка, а не как тип Oracle DATE. Да, PL/SQL или SQL могут неявно преобразовать строку '01- OCT-1986' во внутренний формат даты Oracle1, но обычно в программном коде следует выполнять явные преобразования с использованием встроенных функций. Пример:

TO_DATE('01-OCT-1986', 'DD-MON-YYYY')
TO_TIMESTAMP_TZ('01-OCT-1986 00:00:00 -6','DD-MON-YYYY HH24:MI:SS TZH')

Оба выражения возвращают время 00:00:00 1 октября 1986 года; первое относится к типу данных DATE, а второе — к типу данных временного штампа с часовым поясом. Во второе выражение также включена информация о часовом поясе (–6 — смещение в часах от общемирового времени GMT (UCT)).

В отличие от идентификаторов строковые литералы PL/SQL чувствительны к регистру символов. Как и следовало ожидать, следующие два литерала различаются:

'Steven'
'steven'

А проверка следующего условия возвращает FALSE:

IF 'Steven' = 'steven' 

 

NULL

Отсутствие значения представляется в Oracle ключевым словом NULL. Как показано в предыдущем разделе, переменные почти всех типов данных PL/SQL могут существовать в состоянии NULL (исключение составляют только ассоциативные массивы, экземпляры которых всегда отличны от NULL). Правильная обработка переменных со значением NULL и так является непростой задачей для программиста, а NULL-строки вдобавок требуют особого обращения.

В Oracle SQL и PL/SQL NULL-строка обычно неотличима от литерала из нуля символов, буквально представляемого в виде '' (две одинарные кавычки, между которыми нет ни одного символа). Например, следующее условие равно TRUE как в SQL, так и в PL/SQL: 

'' IS NULL

Если в PL/SQL переменной VARCHAR2(n) присваивается строка нулевой длины, то результат также считается равным NULL:

DECLARE
str VARCHAR2(1) := '';
BEGIN
IF str IS NULL -- равно TRUE 

Такое поведение соответствует правилам обработки столбцов VARCHAR2 в таблицах баз данных.

Но с данными типа CHAR дело обстоит сложнее. Если создать в PL/SQL переменную типа CHAR(n) и присвоить ей строку нулевой длины, база данных дополняет пустую переменную пробелами, в результате чего она становится отличной от NULL:

DECLARE
flag CHAR(2) := ''; -- CHAR(2) присваивается строка нулевой длины
BEGIN
IF flag = ' ' ... -- равно TRUE
IF flag IS NULL ... -- равно FALSE

Как ни странно, такое поведение проявляется только в PL/SQL. В базе данных при вставке строки нулевой длины в поле типа CHAR(n) содержимое столбца не дополняется пробелами, а остается равным NULL!

В этих примерах проявляется частичная поддержка Oracle версий 92 и 99 стандарта ANSI SQL, согласно которому строка нулевой длины должна отличаться от NULL-строки. По утверждениям Oracle, стандарт будет полностью поддерживаться в будущих версиях. Впрочем, разговоры на эту тему идут уже 15 лет и пока этого не произошло.

База данных пытается неявно преобразовать NULL к типу значения, необходимому для текущей операции. Время от времени может возникнуть необходимость в выполнении явных преобразований с использованием синтаксических конструкций вида TO_NUMBER(NULL) или CAST(NULL AS NUMBER).

Использование литералов языка PL/SQL на примерах 

Одинарные кавычки внутри строки

Неприятная сторона работы со строковыми литералами проявляется тогда, когда вам нужно включить в строку одинарную кавычку. До выхода Oracle10g одна литеральная кавычка внутри строки обозначалась удвоением символа кавычки. Примеры:

Литерал (с ограничителем по умолчанию) Фактическое значение
'There''s no business like show business.' There's no business like show business.
'"Hound of the Baskervilles"' "Hound of the Baskervilles"
'''' '
'''hello''' 'hello'
'''''' ''

Например, из этих примеров следует, что для представления литерала из двух одиночных кавычек требуется целых шесть символов. Для упрощения подобных конструкций в Oracle10g появились специальные ограничители. Литерал начинается с символа q, а выражение в ограничителях заключается в одиночные кавычки. В следующей таблице приведены примеры использования этого синтаксиса.

Литерал (со специальными ограничителями) Фактическое значение
q' ( There's no business like show business.) ' There's no business like show business.
q' { "Hound of the Baskervilles" } ' "Hound of the Baskervilles"
q' [ ' ] ' '
q' !'hello' ! ' 'hello'
q' |'' | ' ''

Как видно из примеров, вы можете использовать как простые ограничители (!, | и т. д.), так и «парные»: левая и правая круглые, фигурные и квадратные скобки.

Напоследок следует заметить, что символ двойной кавычки в строковых литералах не имеет специального значения, а интерпретируется так же, как буква или цифра.

 

Числовые литералы

Числовые литералы могут быть целыми или действительными (то есть содержащими дробную часть) числами. Заметьте, что PL/SQL рассматривает число 154.00 как действительное, хотя его дробная часть равна нулю и с точки зрения математики оно является целым. Целые и действительные числа имеют разное внутреннее представление, и преобразование числа из одной формы в другую требует определенных ресурсов.

Для определения числовых литералов может использоваться экспоненциальная (научная) запись. Буква E (в верхнем или нижнем регистре) обозначает степень 10 (например, 3.05E19, 12e–5).

Начиная с версии Oracle Database 10g, вещественные числа могут представляться как типом Oracle NUMBER, так и стандартным типом IEEE 754 с плавающей точкой. К последней категории относятся типы BINARY (32-разрядное; обозначается суффиксом F) и BINARY DOUBLE (64 разрядное; обозначается суффиксом D).

В соответствии со стандартом IEEE, в некоторых выражениях могут использоваться именованные константы из следующей таблицы.

Описание BINARY (32-разрядное) BINARY DOUBLE (64-разрядное)
«Не число» (NaN, Not a Number): результат деления на 0 или недействительной операции BINARY_FLOAT_NAN BINARY_DOUBLE_NAN
Положительная бесконечность BINARY_FLOAT_INFINITY BINARY_DOUBLE_INFINITY
Абсолютное наибольшее число, которое может быть представлено BINARY_FLOAT_MAX_NORMAL BINARY_DOUBLE_MAX_NORMAL
Наименьшее нормальное число; порог потери значимости BINARY_FLOAT_MIN_NORMAL BINARY_DOUBLE_MIN_NORMAL
Наибольшее положительное число, меньшее порога потери значимости BINARY_FLOAT_MAX_SUBNORMAL BINARY_DOUBLE_MAX_SUBNORMAL
Абсолютное наименьшее число, которое может быть представлено BINARY_FLOAT_MIN_SUBNORMAL BINARY_DOUBLE_MIN_SUBNORMAL

 

Логические (булевские) литералы

Для представления логических значений в PL/SQL определено два литерала: TRUE и FALSE. Это не строки и их не нужно заключать в кавычки. Они используются для присваивания значений логическим переменным, как в следующем примере: 

DECLARE
   enough_money BOOLEAN; -- Объявление логической переменной
BEGIN
   enough_money := FALSE; -- Присваивание значения
END;

При проверке логического значения литерал можно не указывать — тип переменной говорит сам за себя:

DECLARE
  enough_money BOOLEAN;
BEGIN
  IF enough_money
  THEN
... 

Логическое выражение, переменная или константа также могут быть равны NULL — неопределенному значению, которое не является ни TRUE, ни FALSE

Вас заинтересует / Intresting for you:

Встроенные методы коллекций PL...
Встроенные методы коллекций PL... 14838 просмотров sepia Tue, 29 Oct 2019, 09:54:01
Управление приложениями PL/SQL...
Управление приложениями PL/SQL... 4651 просмотров Stas Belkov Thu, 16 Jul 2020, 06:20:48
Работа с числами в PL/SQL на п...
Работа с числами в PL/SQL на п... 45198 просмотров Antoniy Mon, 28 May 2018, 16:45:11
Основы языка PL/SQL: использов...
Основы языка PL/SQL: использов... 4700 просмотров Ирина Светлова Tue, 06 Feb 2018, 14:04:03
Войдите чтобы комментировать