
Управл_данными / 16-транзакции
.pdf
Что такое курсор
Операции выборки SQL работают с наборами строк, которые называются результирующие множества.
Все возвращаемые строки являются строками, соответствующими примененному SQL-оператору, их может быть нуль или больше.
При использовании простых операторов SELECT невозможно получить первую строку, последнюю строку или предыдущие 10 строк. Это объясняется особенностями функционирования реляционной СУБД.
Иногда бывает необходимо просмотреть строки в прямом или обратном направлении один или несколько раз. Именно для этого используются курсоры.
Курсор представляет собой запрос к базе данных, хранящийся на сервере СУБД, — это не оператор SELECT, но результирующее множество, выборка, полученная в результате действия оператора SELECT.
После того как курсор сохранен, приложения могут "прокручивать" (просматривать) данные в прямом или обратном направлении, как только возникает такая потребность.
21

Возможности курсоров
Различные СУБД поддерживают разные опции и возможности курсоров. Наиболее часто обеспечиваются следующие:
Возможность помечать курсор как предназначенный только для чтения, в результате чего данные могу считываться, но не могут обновляться или удаляться.
Возможность управлять направлением выполняемых операций (вперед, назад, первая, последняя, абсолютное положение, относительное положение).
Возможность помечать некоторые столбцы как
редактируемые, а другие — как не редактируемые.
Указание области видимости, благодаря чему курсор может быть доступен или для запроса, посредством которого он был создан (например, для хранимой процедуры), или для всех запросов.
Указание СУБД скопировать выбранные данные (в противоположность работе с "живыми" данными в таблицах), чтобы они не изменялись в промежуток времени между открытием курсора и обращением нему.
22

Поведение реляционных СУБД становится похожим на поведение не клиент-серверных
Организация доступа и просмотр строк в такой форме в действительности соответствует применению индекснопоследовательного метода доступа (Indexed Sequential Access Method, ISAM) в базах данных (таких как Btrieve и dBASE).
Курсоры как часть спецификации SQL интересны тем, что с их помощью можно заставить реляционную базу данных вести себя подобно базе данных типа ISAM.
Курсоры используются главным образом интерактивными приложениями, предоставляющими пользователям возможность прокручивать отображаемые на экране данные вперед и назад, просматривать их или изменять.
23

Курсоры и Web-приложения
Курсоры практически бесполезны, если их применять к приложениям, основанным на Webтехнологиях (например, таких как ASP, ColdFusion, PHP и JSP).
Курсоры предназначены для использования в течение сеанса связи между клиентским приложением и сервером, но эта модель "клиентсервер" не годится для мира Web-приложений, потому что сервер приложений является клиентом базы данных, а не конечным пользователем.
По этой причине большинство разработчиков Webприложений избегают использования курсоров и добиваются выполнения нужных функций, если это необходимо, другими средствами.
24

Работа с курсорами
Работу с курсором можно разделить на несколько четко выраженных стадий:
1)Прежде чем курсор может быть использован, его следует объявить (определить). В ходе этого процесса выборка данных не производится, просто определяется оператор SELECT, который будет использован, и некоторые опции курсора.
2)После объявления курсор должен быть открыт для использования. В ходе этого процесса уже производится выборка данных согласно предварительно определенному оператору SELECT.
3)После того как курсор заполнен данными, могут быть извлечены (выбраны) отдельные необходимые строки.
4)После того как это сделано, курсор должен быть закрыт и, возможно, должны быть освобождены ресурсы, которые он занимал (в зависимости от СУБД).
После того как курсор объявлен, его можно открывать и закрывать столь часто, сколько необходимо.
Если курсор открыт, операция выборки может выполняться так часто как необходимо.
25

Создание курсора
Курсоры создаются с помощью оператора DECLARE, синтаксис которого различен для разных СУБД.
Оператор DECLARE дает курсору имя и принимает оператор SELECT дополненный при необходимости предложением WHERE и другими.
Пример для DB2, SQL Server и Sybase:
DECLARE Cursor_01 CURSOR FOR
SELECT * FROM Client WHERE email IS NULL
Версия для Oracle и PostgreSQL:
DECLARE CURSOR Cursor_01 IS
SELECT * FROM Client WHERE email IS NULL
После того как курсор определен, его можно открыть.
26

Открытие курсора
Курсоры открываются с помощью оператора OPEN CURSOR, синтаксис которого настолько прост, что его поддерживают большинство СУБД:
OPEN CURSOR Cursor_01
При обработке оператора OPEN CURSOR выполняется запрос, и выборка данных сохраняется для последующих просмотра и прокрутки.
27

Использование курсора
Если курсор открыт, к данным этого курсора может быть получен доступ с помощью оператора FETCH.
Оператор FETCH указывает строки, которые должны быть выбраны, откуда они должны быть выбраны и где их следует сохранить (имя переменной).
В первом примере используется синтаксис Oracle для выборки одной строки курсора (первой).
Здесь оператор FETCH используется для выборки текущей строки в переменную, объявленную с именем CustRecord. С выбранными данными ничего не делается.
DECLARE TYPE Cursor_01 IS REF CURSOR
RETURN Client%ROWTYPE;
DECLARE CustRecord Client%ROWTYPE
BEGIN
OPEN Cursor_01;
FETCH Cursor_01 INTO CustRecord;
CLOSE Cursor_01;
END;
28

Пример 2
DECLARE TYPE Cursor_01 IS REF CURSOR
RETURN Client%ROWTYPE;
DECLARE CustRecord Client%ROWTYPE
BEGIN
OPEN Cursor_01;
LOOP
FETCH CustCursor INTO CustRecord;
EXIT WHEN CustCursor%NOTFOUND;
...
END LOOP;
CLOSE Cursor_01;
END;
Аналогично предыдущему примеру, здесь используете оператор FETCH для выборки текущей строки в переменную, объявленную с именем CustRecord.
Однако в отличии от предыдущего примера, здесь оператор FETCH находится внутри цикла LOOP, так что он выполняется снова и снова.
Код EXIT WHEN CustCursor%NOTFOUND указывает, что это процесс должен быть завершен (выход из цикла), когда больше не останется строк для выборки.
В этом примере также не выполняется никакой обработки, тогда как в реальном коде вам следовало бы заменить ... вашим собственным кодом.
29

Пример с использованием синтаксиса Microsoft SQL Server
|
|
|
DECLARE |
@id CHAR(10), |
@address CHAR(50), |
@name |
CHAR(50), |
|
@city |
CHAR(50), |
@state CHAR(5), |
@ZIP CHAR(10), |
@country CHAR(50), |
|
@contact CHAR(50), |
@email CHAR(255), |
OPEN CustCursor
FETCH NEXT FROM CustCursor
INTO @id, @name, @address, @city, @state, @ZIP, @country, @contact, @email
WHILE @@FETCH_STATUS = 0
BEGIN
…
END
FETCH NEXT FROM CustCursor INTO @id, @name, @address, @city, @state, @ZIP, @country, @contact, @email
CLOSE CustCursor
30