Чтение онлайн

на главную - закладки

Жанры

Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ

Борри Хелен

Шрифт:

Контекстные переменные могут применяться везде, где могут быть использованы обычные переменные. Значение NEW для столбца строки может быть изменено только до соответствующего действия. Значения OLD являются значениями только для чтения. Подробности и примеры использования см. в главе 31.

! ! !

СОВЕТ. Поскольку Firebird создает триггеры для реализации ограничений CHECK, контекстные переменные OLD и NEW могут использоваться непосредственно в ограничениях CHECK, например:

ALTER TABLE EMPLOYEE

ADD CONSTRAINT EMPLOYEE_SALARY_RAISE_CK

CHECK ((OLD.SALARY IS NULL) OR (NEW.SALARY > OLD.SALARY));

. ! .

Операторы 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, которые возвращают множество строк в хранимые процедуры, и технику написания хранимых процедур выбора.

Поделиться:
Популярные книги

Шайтан Иван 2

Тен Эдуард
2. Шайтан Иван
Фантастика:
боевая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Шайтан Иван 2

Наследник старого рода

Шелег Дмитрий Витальевич
1. Живой лёд
Фантастика:
фэнтези
8.19
рейтинг книги
Наследник старого рода

Аргумент барона Бронина 2

Ковальчук Олег Валентинович
2. Аргумент барона Бронина
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Аргумент барона Бронина 2

Третье правило дворянина

Герда Александр
3. Истинный дворянин
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Третье правило дворянина

Убивать чтобы жить 3

Бор Жорж
3. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 3

СД. Том 15

Клеванский Кирилл Сергеевич
15. Сердце дракона
Фантастика:
героическая фантастика
боевая фантастика
6.14
рейтинг книги
СД. Том 15

Жена неверного маршала, или Пиццерия попаданки

Удалова Юлия
Любовные романы:
любовно-фантастические романы
4.25
рейтинг книги
Жена неверного маршала, или Пиццерия попаданки

Мымра!

Фад Диана
1. Мымрики
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Мымра!

Идеальный мир для Лекаря 12

Сапфир Олег
12. Лекарь
Фантастика:
боевая фантастика
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 12

Оцифрованный. Том 1

Дорничев Дмитрий
1. Линкор Михаил
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Оцифрованный. Том 1

Элита элит

Злотников Роман Валерьевич
1. Элита элит
Фантастика:
боевая фантастика
8.93
рейтинг книги
Элита элит

Хуррит

Рави Ивар
Фантастика:
героическая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Хуррит

Шаман. Похищенные

Калбазов Константин Георгиевич
1. Шаман
Фантастика:
боевая фантастика
попаданцы
6.44
рейтинг книги
Шаман. Похищенные

Курсант: Назад в СССР 4

Дамиров Рафаэль
4. Курсант
Фантастика:
попаданцы
альтернативная история
7.76
рейтинг книги
Курсант: Назад в СССР 4