|
Программирование >> Построение запросов sql
других действий. Для таких целей в модулях на 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, внутри которого
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |