В версии 1.5 и более поздних в наборах, отличных от UNION, условие упорядочения может быть выражением, возвращающим значение, которое может оказаться осмысленным для упорядочения. Например, предложение ORDER BY В следующем операторе вызывает функцию, которая возвращает длину столбца описания и использует ее для упорядочения выходного набора от большего к меньшему:
SELECT DOCUMENTED, TITLE, DESCRIPTION FROM DOCUMENT
ORDER BY STRLEN(DESCRIPTION) DESC;
В SQL оператор GROUP BY используется для собирания наборов данных и иерархической их организации или суммирования.
Во всех версиях Firebird вы можете выполнять иерархическое группирование, основанное на вызове внешней функции (UDF), однако в версии 1.0.x вы не можете использовать порядковый номер выходного столбца в качестве условия группирования. Firebird 1.5 добавляет возможность использования в GROUP BY порядкового номера, а также несколько других типов выражений, включая выражения подзапросов.
Другие изменения в Firebird 1.5 ужесточают отдельные правила группирования, убирая поддержку некоторых неправильных вариантов синтаксиса группирования, которые были допустимы в Firebird 1.0.x.
Правила и взаимодействия выражений для группирования и упорядочения иногда являются сложными в реализации. Эти темы подробно обсуждаются в главе 23.
Следующий пример для версии 1.5 запрашивает в таблице MEMBERSHIP и выводит статистику, показывающую количество участников, объединенных в каждом месяце:
SELECT
MEMBER_TYPE,
EXTRACT(MONTH FROM J0IN_DATE) AS MONTH_NUMBER,
/* 1, 2, и т.д. */
F_CMONTHLONG(JOIN_DATE) AS SMONTH,
/* UDF, возвращающая месяц в виде строки */
COUNT (*) AS MEMBERS_JOINED
FROM MEMBERSHIP
GROUP BY
MEMBER_TYPE, EXTRACT(MONTH FROM JOIN_DATE);
Выражения CHECK в DDL
Применение выражений не ограничивается только DML; мы уже видели их использование в определении таблицы для описания вычисляемых столбцов. Каждый раз, когда вы определяете ограничение CHECK для таблицы, столбца или домена, вы применяете выражения. По своей природе ограничение CHECK выполняет проверку на одно или более значений - тестирует предикат. Вот пример, где проверяется номер сотового телефона участника, который должен начинаться с нуля, если номер вообще присутствует:
ALTER TABLE MEMBERSHIP
ADD CONSTRAINT CHECK_CELLPHONE _NO
CHECK (CELLPHONE_NO IS NULL OR CELLPHONE_NO STARTING WITH '0');
Выражения в PSQL
Процедурный язык для триггеров и хранимых процедур PSQL широко использует выражения для управления потоком выполнения. PSQL предоставляет структуры IF(<предикат>) THEN и WHILE(<предикат>) DO. Любой предикат, который может быть использован в условии поиска, также может быть предикатом для условия управления потоком в программе.
Важной функцией триггеров является проверка с использованием выражений поступающих новых значений, а также использование других выражений для преобразования или создания значений для текущей строки или для строк в связанных таблицах. Например, следующий общий триггер проверяет, является ли значение NULL, и если да, то вызывает функцию для присваивания ему значения:
CREATE TRIGGER BI_MEMBERSHIP FOR MEMBERSHIP
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
IF (NEW.MEMBER_ID IS NULL) THEN
NEW. MEMBER_I D - GEN_ID(GEN_MEMBER_ID, 1);
END
Подробную информацию о написании триггеров и хранимых процедур см. в части VII.
Вызовы функций
После установки Firebird содержит минимальный набор внутренних функций SQL. Хотя новые функции появляются время от времени, тем не менее сохраняется одно из основных достоинств Firebird: малый объем памяти, занимаемый сервером.
Функциональные возможности сервера могут быть легко расширены за счет его возможности получать доступ к функциям из внешних библиотек. Традиционно такие функции называются функциями, определенными пользователями (User-Defined Functions, UDF). Более корректно называть их внешними библиотеками функций. В реальности большинство администраторов баз данных используют хорошо протестированные библиотеки, находящиеся в общем пользовании и свободно распространяемые.
Внутренние функции SQL
В табл. 21.7 представлены внутренние функции SQL, доступные в Firebird.
Таблица 21.7. Внутренне реализованные функции SQL