Предложение PLAN позволяет включить план запроса в спецификацию запроса. План является инструкцией оптимизатору по использованию отдельных индексов, порядка соединения и методов доступа для запроса. Оптимизатор создает свой собственный план при подготовке оператора запроса. Вы можете просматривать план в isql и многих других доступных утилитах графического интерфейса. Обычно "оптимизатор знает лучше", но у вас может быть опыт использования различных планов оптимизатора, когда запрос работал медленно.
Планы запросов и синтаксис выражений плана обсуждаются в разд. "Тема оптимизации" главы 22.
Используйте это предложение, когда вам нужно сортировать выходной набор. Например, следующий оператор дает список имен, отсортированный в алфавитном порядке по фамилии и имени:
SELECT EMP_NO, LAST_NAME, FIRST_NAME FROM EMPLOYEE
ORDER BY LAST_NAME, FIRST_NAME;
В отличие от столбцов GROUP BY столбцы в ORDER BY не обязательно должны присутствовать в выходной спецификации (предложение SELECT). Идентификатор любого упорядочиваемого столбца, который также появляется в выходной спецификации, может быть заменен на его порядковый номер в выходной спецификации при подсчете слева направо:
SELECT EMP_NO, LAST_NAME, FIRST_NAME FROM EMPLOYEE
ORDER BY 2, 3;
Обратите особое внимание на индексы для столбцов, которые будут использованы для сортировки (см. главу 18). Подробнее о синтаксисе и проблемах см. в главе 23.
Его синтаксис:
[FOR UPDATE [OF col1 [,col2..]] [WITH LOCK]]
Вообще говоря, предложение FOR UPDATE имеет смысл только в контексте оператора SELECT, который используется для задания именованных курсоров. Оно указывает серверу, чтобы тот ждал вызова FETCH, читал бы одну строку в курсор для операции "текущей строки" и затем ожидал бы следующий вызов FETCH. После того как все записи будут прочитаны, они становятся доступными для операций изменения.
Необязательное внутреннее предложение OF <список-столбцов> может быть использовано для задания списка присутствующих в курсоре полей, которые могут быть изменены.
* В приложениях ESQL оператор DECLARE CURSOR используется для объявления именованного курсора. Подробную информацию см. в документации по InterBase 6.0 "Embedded SQL".
¦- Приложения интерфейса DSQL должны использовать функцию isc_dsqi_set_ cursor name для получения именованного курсора и осмысленно использовать FOR UPDATE. Более подробную информацию см. в InterBase API Guide.
Поскольку в DSQL отсутствует FETCH как элемент языка, приложения реализуют его с помощью вызова функции API С именем isc_dsql_fetch.
API "знает" порядок и формат выходных полей, потому что динамическое приложение должно передавать ему описательную структуру- называемую расширенной областью дескрипторов SQL (Extended SQL Descriptor Area, XSQLDA). Одна структура XSQLDA содержит массив описателей сложных переменных, называемых SQLVAR, по одному на каждое выходное поле.
Клиентское приложение использует isc_dsqi_fetch для запроса строки, которая только что заполнила XSQLDA. Обычное поведение большинства современных клиентских приложений- выполнение в цикле обращений к isc_dsqi_fetch для получения выходных строк в пакете и буферизация их в структурах клиентской стороны, которые называются наборами записей, наборами данных или результирующими наборами.
Некоторые приложения API реализуют именованные курсоры и используют поведение TOR UPDATE, однако большинство этого не делают.
Firebird 1.5 вводит необязательное расширение WITH LOCK, используемое с/без предложения FOR UPDATE, для поддержки ограниченного уровня явной пессимистической блокировки (pessimistic locking) на уровне строки. Пессимистическая блокировка является прямой противоположностью архитектуры транзакций в Firebird и добавляет запутанность. Ее использование рекомендуется только тем разработчикам, которые хорошо понимают, как параллельная работа многих пользователей реализована в Firebird. Пессимистическая блокировка обсуждается в главе 27.
Запросы, подсчитывающие строки
Среди некоторых программистов существует закрепившаяся практика разработки приложений, которым нужно выполнить подсчет строк в выходном наборе. В Firebird не существует быстрого надежного способа получения количества строк, возвращаемых в выходном наборе. Поскольку Firebird имеет многоверсионную архитектуру, у него нет механизма "узнавать" количество строк в постоянных таблицах. Если приложению требуется количество строк, оно может получить приблизительное значение с использованием запроса SELECT COUNT (*).
Оператор SELECT с вызовом функции COUNT() на месте идентификатора столбца вернет приблизительную мощность набора, определенного в предложении WHERE. Функция COUNT() принимает практически все в качестве входного аргумента: идентификатор столбца, список столбцов, символ *, который представляет "все столбцы", и даже константу.