Программирование >>  Построение запросов sql 

1 ... 70 71 72 [ 73 ] 74 75 76 ... 101


других действий. Для таких целей в модулях на PSQL допускается использовать запрос на выборку следующего вида: SELECT INTO <список переменных>;.

Однако запрос такого вида можно использовать только в случае, если он возвращает одно единственное значение (скалярный запрос) или только одну строку из одной или нескольких таблиц БД.

В большинстве случаев запрос к реляционной базе данных возвращает несколько записей данных, но приложение за один раз обрабатывает лишь одну запись. При модификации, удалении или добавлении данных с помощью запросов DML действия выполняются также над отдельной записью (строкой) таблицы. В этой ситуации на первый план выступает концепция курсора. Под курсором понимается получаемый при выполнении запроса результирующий набор и связанный с ним указатель текущей записи. Обычно курсоры используются для выбора из базы данных некоторого подмножества хранимой в ней информации. В каждый момент времени прикладной программой может быть обработана одна строка курсора. После позиционирования курсора над этой строкой можно выполнять различные действия.

Курсоры часто применяются в запросах SQL, встроенных в прикладные программы, написанные на языках процедурного типа.

PSQL СУБД Firebird поддерживает два типа курсоров: явные и неявные. Реализация неявного курсора представлена следующей конструкцией:

FOR SELECT ... INTO DO .

Она полностью реализует синтаксис цикла и предоставляет возможность последовательной построчной обработки набора данных курсора в цикле FOR.

Явный курсор, также называемый изменяемым или именованным курсором, представляет собой объект, который разработчик может явно объявлять, открывать и закрывать (в отличие от неявного курсора, не требующего объявления, открытия и закрытия). Для управления явным курсором

используются команды DECLARE CURSOR, OPEN, FETCH и CLOSE.

Рассмотрим более подробно особенности этих двух реализаций курсора. 6.1.3.1. Неявный курсор

Как известно, запрос SELECT возвращает таблицу результатов запроса, но приложения не всегда могут эффективно работать с результирующим набором. Возникает проблема доступа к каждой строке этой таблицы, которая может быть решена при использовании неявного курсора.

В процедурном языке Firebird цикл для построчной обработки набора данных неявного курсора организуется с помощью следующей конструкции:

SELECT [DISTINCT ALL]

{ <возвращаемый элемент1> [, <возвращаемый элемент2> ] FROM базовая таблица1 [, базовая таблица2 ]



[WHERE <условие поиска>]

[GROUP BY <элемент группировки1> [, <элемент группировки2>] [HAVING <условие поиска>[

[ORDER BY <элемент сортировки1> [, <элемент сортировки2>] [

INTO :<имя переменной1> [, :<имя переменной2> [AS CURSOR имя курсора] DO <группа операторов>,

<имя переменной>:: = {имя локальной переменной

вхоцной параметр выхоцной параметр}.

Как следует из приведенного синтаксиса, набор данных курсора определяется запросом SELECT, который может соединять данные из нескольких таблиц, содержать условия поиска, сортировку и т.д.

Для обработки всех строк, возвращаемых запросом SELECT, организуется цикл. При этом в запросе SELECT используется предложение INTO. Оно определяет, что значения возвращаемых элементов должны быть присвоены переменным, определенным в теле ХП, триггера или блока. Предложение INTO в запросе SELECT должно быть последним, если он имеет другие предложения (например, WHERE).

Каждый раз, когда обрабатывается очередная строка в цикле, значения возвращаемых элементов присваиваются переменным, указанным в предложении INTO. При этом <группа операторов> выполняется один раз для каждой строки, сформированной запросом SELECT. Цикл повторяется, пока не закончатся записи в наборе данных курсора.

Например, в теле ХП использование неявного курсора может выглядеть следующим образом:

DECLARE LAccountCD VARCHAR(6); DECLARE LFio VARCHAR(20); DECLARE LPayDate DATE;

DECLARE LPaySum NUMERIC(15,2);

BEGIN

FOR SELECT A. AccountCD, A.Fio, P. PayDate, P. PaySum FROM Abonent A, PaySumma P

WHERE A. AccountCD = P. AccountCD AND P. PaySum > 70 INTO :LAccountCD, :LFio, :LPayDate, :LPaySum

SUSPEND; END.

Следует отметить важную особенность работы с курсорами. Они позволяют обеспечить обновление или удаление строки, на которой в данный момент установлен курсор, с помощью конструкции WHERE CURRENT OF в запросе UPDATE или DELETE. В этом случае <группа операторов> при обновлении строки, на которой установлен курсор, должна выглядеть следующим образом:

UPDATE базовая таблица

SET WHERE CURRENT OF имя курсора;.



При удалении строки, на которой установлен курсор, <группа операторов> должна выглядеть следующим образом: DELETE FROM базовая таблица WHERE CURRENT OF имя курсора;.

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

6.1.3.2. Явный курсор

Работа с явным курсором предполагает его определение, связывание с ним запроса SELECT, открытие, выборку данных из курсора и его закрытие.

Для определения явного курсора и связывания с ним запроса SELECT используется следующий оператор:

DECLARE [VARIABLE] имя курсора CURSOR FOR (<запрос 8е1ес!>);. Для открытия курсора используется следующий оператор:

OPEN имя курсора;. Для выборки данных из курсора используется следующий оператор:

FETCH имя курсора INTO :<имя переменной1> [, :<имя переменной2> ...];. Для закрытия курсора используется следующий оператор:

CLOSE имя курсора;.

Примечание. Команды OPEN, FETCH и CLOSE, используемые для работы с явным курсором, нельзя применять для работы с неявным курсором.

Объявление курсора должно помещаться в начале триггера, ХП или неименованного выполняемого блока (заданного с помощью EXECUTE BLOCK), подобно объявлению обычных локальных переменных.

Например, в теле ХП объявление и использование явного курсора может выглядеть следующим образом:

DECLARE Aname CHAR(31);

DECLARE с CURSOR FOR (SELECT Fio FROM Abonent); BEGIN

OPEN c;

WHILE (1 = 1) DO

BEGIN

FETCH c INTO :Aname;

IF (ROW COUNT = 0) THEN

LEAVE; SUSPEND; END

CLOSE c; END.

В данном примере показано, как может быть организована выборка данных с использованием явного курсора. Организуется цикл WHILE, внутри которого



1 ... 70 71 72 [ 73 ] 74 75 76 ... 101

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика