
Прочие функции
В этом разделе представлена группа SQL-функций, которые объединяет лишь то, что их нельзя отнести ни к какой другой группе. Впрочем, это ни в коей мере не снижает их ценность.
DECODE
Одним из различий между языком SQL и языком программирования PL/SQL является то, что SQL не позволяет управлять последовательностью выполнения команд — в нем нет циклов, операторов goto, if-then-else. Сценарий на языке SQL (SQL-сценарий) выполняется сверху вниз, строка за строкой, без ветвлений. В SQL отсутствуют средства принятия решений, но есть одна функция, которая в чем-то аналогична оператору if-then-else. Эта функция DECODE, которая транслирует одно множество данных в другое, используя определенные вами значения "до" и "после". Охарактеризовать ее работу можно так: если входное значение равно "А", на выходе будет "В", а если входное значение равно "С", функция вернет "D". Значения "А", "В", "С" и "D" задаются при вызове функции. Это может потребоваться при трансляции данных из одной системы, включающей в свой состав базы данных, в другую, поскольку разные системы обычно используют разные множества кодов для представления схожей информации.
Функция DECODE имеет следующий синтаксис:
DECODE(ucmoчник_вxoдных_данных,входное_знанение_1, выходное_значение_1,
входное_значение_2, выходное_значение_2,
…
последнее_входное_значение, последнее_выходное_значение,
[выходное_значение_по_умолчанию_при_отсутствйи_совпадений]
)
При использовании этой функции надо иметь в виду следующие ее особенности:
• после указания источника_входных_данных (обычно это имя столбца некоторой таблицы, но может быть и выражение) задаются пары входных/выходных значений. Слева располагается одно из значений, которые будут поступать из источника данных, а справа — то, во что вы хотите транслировать это значение. Можно определить сколько угодно таких пар (именно это обозначает многоточие между строками);
• определив пары входных/выходных значений, можно отдельно указать конечный результат, которому не соответствует какое-либо определенное входное значение. Он будет возвращен в том случае, если функция DECODE встретит значение, отсутствующее в списке (по аналогии с блоком else оператора if-then-else). Эта часть функции необязательна (поэтому и заключена в квадратные скобки), но обычно ее стоит указывать, чтобы знать, не встретились ли среди входных данных какие-нибудь значения, которые не ожидались.
Чтобы продемонстрировать работу функции DECODE, предположим, что дана таблица OLD_ITEM и нужно выбрать из нее некоторый набор записей. Однако со времени использования старых изделий структура предприятия изменилась, и теперь вместо идентификации изделий по городу, откуда они поступили, необходимо показывать регионы. Изделия, идентификатор которых содержит "NY", относятся к восточному региону ("Eastern"), а изделия "LA" поступают из западного ("Western") региона. Трехзначные номера, следующие за сокращенными названиями городов, по-прежнему должны отображаться, поэтому придется использовать функцию SUBSTR, чтобы выделять подстроки с этими номерами. Ниже показано, как использовать функцию DECODE для трансляции городов в регионы.
SELECT DECODE(SUBSTR(item_id, 1, 2), 'LA', 'Western', 'NY', 'Eastern',
'* Unknown *'
) "Region",
SUBSTR(item_id, 4,3) "Item ID", item_desc
FROM old_item;
В одном и том же операторе SELECT на данный столбец может ссылаться более одной функции DECODE, а функция DECODE может возвращать значение столбца, отличного от того, который использовался для принятия решения.
NVL
Функция NVL выполняет простую, но важную задачу: получив в качестве аргумента null-значение, она возвращает вместо него выбранное вами значение. Автоматическое заполнение пустых полей помогает придавать выходным данным более законченный вид. Эта функция имеет следующий синтаксис:
NVL(входное_значение , результат_если_пиll)
Как и во многих других функциях, входное_значение обычно представляет собой имя столбца. Результат_если_null может быть всем, чем угодно: литералом (т.е. жестко закодированным значением), ссылкой на другой столбец или произвольным выражением.
Пример использования функции NVL показан ниже:
SELECT product_name,
NVL(last_stock_date, '01-JAN-2007') "Last Stocked"
FROM product;
Функция NVL будет заменять пустое значение LAST_STOCK_DATE указанной датой. Можно было бы заменить null на текущую дату, использовав следующий код:
SELECT product_name,
NVL(last_stock_date, TRUNC(SYSDATE)) "Last Stocked"
FROM product;
При выполнении функция NVL не обновляет никаких значений. Исходные данные в таблице остаются нетронутыми.
У функции NVL есть одна особенность: она ожидает, что входное_значение и результат_если_null будут иметь один и тот же тип данных. Если входное_значение — дата, то результат_если_null также должен быть датой, и т,д. Это становится проблемой, если требуется выводить популярное "N/A" (Not Assigned) для null-значений, поскольку "N/A" является текстом. Когда столбец, полученный функцией в качестве входного_значения, имеет текстовый тип, все в порядке. Но если функция проверяет на наличие null-значений числовой столбец или столбец с датами, то придется подставить имя столбца в функцию TO_CHAR, чтобы входное значение также было текстом. Это демонстрируется приведенными ниже примерами. Первая команда завершится выдачей сообщения об ошибке, тогда как вторая будет успешно выполнена.
SELECT product_name,
NVL (last_stock_date, 'N/A') "Last Stocked"
FROM product;
SELECT product_name,
NVL (TO_CHAR(last_stock_date), 'N/A') "Last Stocked"
FROM product;