Книга: Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
Операторы SELECT ... INTO
Разделы на этой странице:
Операторы SELECT ... INTO
Используйте оператор SELECT С предложением INTO для поиска значений столбцов в таблицах и сохранения их в локальных переменных или выходных аргументах.
Одиночный оператор SELECT
Обычный оператор SELECT В PSQL должен возвращать не более одной строки из базы данных- стандартный одиночный (singleton) оператор SELECT. ЕСЛИ оператор возвращает более одной строки, то будет выдано исключение. Предложение ORDER BY недопустимо в одиночном SELECT кроме случая, когда используется оператор SELECT FIRST 1. (Информацию об использовании квалификатора FIRST см. В znaee 21.)
Обычные правила применяются к входному списку, предложению WHERE и предложению GROUP BY, если оно используется. Предложение INTO требуется и должно быть последним предложением в операторе.
Пример одиночного оператора SELECT В параметризованном запросе DSQL в приложении:
SELECT SUM(BUDGET), AVG(BUDGET)
FROM DEPARTMENT
WHERE HEAD_DEPT = :head_dept;
Для использования этого оператора в процедуре объявите локальные переменные или выходные аргументы и добавьте предложение INTO в конец:
. . .
DECLARE VARIABLE TOT_BUDGET NUMERIC(18,2);
DECLARE VARIABLE AVG_BUDGET NUMERIC(18,2);
. . .
SELECT SUM(BUDGET), AVG(BUDGET)
FROM DEPARTMENT
WHERE HEAD_DEPT = :head_dept
INTO :tot_budget, :avg_budget;
Операторы SELECT для множества строк
Любой модуль PSQL может оперировать с множеством входных строк, полученных из оператора SELECT, когда он содержит структуру цикла, который может "перемещаться" по набору и выполнять одинаковую обработку каждой строки. PSQL не может обрабатывать многострочные наборы другим способом, и при отсутствии контекста цикла многострочная выборка данных вызовет исключение ("Multiple rows in singleton select" - "Множество строк в одиночном операторе SELECT").
Циклы FOR SELECT...
Основным методом реализации структуры цикла для обработки многострочных входных наборов является структура FOR ... SELECT ... INTO ... DO. Его упрощенный синтаксис:
FOR SELECT <список-спецификации-набора>
FROM имя-таблицы
[JOIN..]
[WHERE..]
[GROUP BY. . ]
[ORDER BY. . ]
INTO <список-переменных> DO
BEGIN
< блок-обработки>
. . .
[SUSPEND] ;
END
В качестве примера рассмотрим следующую процедуру, получающую набор от оператора SELECT, который передает строки, по одной за один раз, в буфер курсора процедуры. Она проходит по набору, устанавливая значения для набора переменных в соответствии со спецификацией таблицы. В конце цикла процедура добавляет запись во внешнюю таблицу.
CREATE PROCEDURE PROJECT_MEMBERS
AS
DECLARE VARIABLE PROJ_NAME CHAR(23);
DECLARE VARIABLE EMP_NO CHAR(6);
DECLARE VARIABLE LAST_NAME CHAR(23);
DECLARE VARIABLE FIRST_NAME CHAR (18);
DECLARE VARIABLE HIRE_DATE CHAR(12);
DECLARE VARIABLE JOB_TITLE CHAR(27) ;
DECLARE VARIABLE CRLF CHAR (2);
BEGIN
CRLF = ASCII_CHAR(13) || ASCII_CHAR(10);
/* Windows EOL - признак конца строки */
FOR SELECT DISTINCT
P.PROJ_NAME,
E.EMP_NO,
E.LAST_NAME,
E.FIRST_NAME,
E.HIRE_DATE,
J.JOB_TITLE
FROM EMPLOYEE E
JOIN JOB J ON E.JOB_CODE = J.JOB_CODE
JOIN EMPLOYEE_PROJECT EP ON E.EMP_NO = EP.EMP_NO
JOIN PROJECT P ON P.PROJ_ID = EP.PROJ_ID
ORDER BY P.PROJ_NAME, E.LAST_NAME, E.FIRST_NAME
INTO /* переменные для столбцов */
:PROJ_NAME, :EMP_NO, :LAST_NAME, :FIRST_NAME,
:HIRE_DATE, :JOB_TITLE
DO
BEGIN /* начинает цикл присваивания значений переменным */
PROJ_NAME = ""И CAST (PROJ_NAME AS CHAR(20) ) || "" ||' , ' ;
EMP_NO = CAST (EMP_NO AS CHAR (5) ) || ' , ' ;
LAST_NAME = ""|| CAST (LAST_NAME AS CHAR(20) ) || "" ||' , ' ;
FIRST_NAME = ""|| CAST (FIRST_NAME AS CHAR (15) ) || "" || ' , ';
HIRE_DATE = CAST(HIRE_DATE AS CHAR(11)) || ' , ';
JOB_TITLE = ""|| CAST (JOB_TITLE AS CHAR (25) ) || "" ;
INSERT INTO EXT_FILE
VALUES (:PROJ_NAME, :EMP_NO, :LAST_NAME,
:FIRST_NAME,:HIRE_DATE, :JOB_TITLE,
CRLF) ;
END /* завершает цикл DO */
END ^
! ! !
ВНИМАНИЕ! Если выходному параметру не присваивается значение, его значение будет непредсказуемым, что может привести к ошибкам. Процедура должна обеспечить инициализацию всех выходных параметров до начала процесса присваивания значений; это должно гарантировать, что оператор SUSPEND передаст допустимые выходные данные.
. ! .
SUSPEND
Оператор SUSPEND имеет специфическое использование в конструкции FOR ... SELECT ... INTO ... DO. Если SUSPEND включен в цикл DO, то после того, как SELECT прочтет строку в переменные строки, цикл будет ждать, когда эта строка будет выведена в кэш строк сервера перед получением следующей строки из курсора SELECT. Такая операция позволяет создавать в Firebird хранимые процедуры выбора.
В следующей главе мы более подробно рассмотрим использование операторов SELECT, которые возвращают множество строк в хранимые процедуры, и технику написания хранимых процедур выбора.
Оператор SUSPEND недопустим в триггерах. В выполняемых хранимых процедурах он имеет тот же эффект, что и оператор EXIT - т. е. он немедленно завершает процедуру, а все операторы, следующие за ним, никогда не будут выполняться.
По контрасту, если процедура выбора имеет выполняемые операторы, следующие за последним оператором SUSPEND В процедуре, то все эти операторы будут выполнены, даже если нет больше строк, возвращаемых вызвавшей программе. Процедуры такого рода завершаются финальным оператором END.
- Конструкция FOR SELECT ... DO
- Циклы и операторы ветвления
- Арифметические операторы
- Инструкция INSERT INTO ... FROM ... UNION ...
- 1.2.4. Операторы и приоритеты
- Условные операторы
- 1. Оператор Select – базовый оператор языка структурированных запросов
- Поразрядные операторы
- Глава 6. Wi-Fi для Macintosh
- 2.3.3 Selecting and Pasting
- Логические операторы
- Максимальное число дескрипторов для функции select