Книга: 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.

Оглавление книги


Генерация: 0.909. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз