Зачем нужен курсор в sql
В прошлый раз, я заморочил вам голову с аналогиями! Но надеюсь, что понятие транзакция для вас не пустой звук! 🙂 Что ж, давайте определим, что же такое «курсор». Если говорить по большому счету понятие курсор в серверах SQL является фундаментальным и вот почему. Все базовые операторы DML — это не что иное, как — да! да! «курсоры». При выполнении INSERT, UPDATE и т.д. в «глобальной системной области», (применительно к Oracle) — всегда, открывается «курсор»! Курсоры имеют ряд атрибутов для облегчения работы с ними. Так же курсоры могут быть явными и не явными. Кстати все операторы DML (благо их не так много) — это не что иное, как неявные курсоры. Так же курсоры могут быть параметризованные или нет. Что ж, много всего навалилось, давайте разбирать это все последовательно. Итак, немного анатомии курсора сервера Oracle. При обработке SQL — операторов Oracle выделяет область памяти называемую «контекстной областью» (context area). Она содержит информацию необходимую для начала и завершения обработки SQL оператора. В том, числе — число строк обрабатываемых оператором, указатель на представление этого оператора после синтаксического анализа (еще это называют парсинг) и активный набор (active set) — например набор строк возвращаемых запросом.
Итак: КУРСОР — это указатель (хотя как такового, понятия «указатель» в PL/SQL нет!) на контекстную область памяти, с помощью которого программа на языке PL/SQL может управлять контекстной областью и ее состоянием во время обработки оператора.
Объявление курсора определяет какое выражение языка SQL — будет передано программе SQL Statement Executor (системе исполнителю выражения SQL). Курсор может представлять собой любое допустимое предложение языка SQL! Так же, курсор является основным базовым «кирпичиком» для построения блоков PL/SQL. Курсоры обеспечивают циклический механизм оперирования наборами данных в БД. Курсор может возвращать одну или несколько строк данных или вообще ни одной.
- Объявление курсора и структуры данных, в которую, будут помещены найденные строки.
- Открытие курсора.
- Последовательная выборка данных.
- Закрытие курсора.
Полный синтаксис определения явного курсора таков:
------ CURSOR -- имя (передаваемые параметры) --- IS ----- ---------------- SELECT список полей FROM таблица выбора ---------------- WHERE условия выбора в курсор -----------
Вот так определяется явный курсор. Давайте запишем несколько определений курсоров, и вы посмотрите как это делается. Если пока что-то не понятно можете не расстраиваться, я все поясню по ходу.
DECLARE -- 1. -- Выбрать все заказы: CURSOR get_orders IS SELECT * FROM ORDERS; -- 2. -- Выбрать несколько столбцов -- для определенного номера заказа CURSOR get_orders(Pord_num ORDERS.order_num%TYPE) IS SELECT ORDER_DATE, MFR, AMOUNT FROM ORDERS WHERE order_num = Pord_num; -- 3. -- Получить полную запись -- для определенного номера заказа CURSOR get_orders(Pord_num ORDERS.order_num%TYPE) IS SELECT * FROM ORDERS WHERE order_num = Pord_num RETURN ORDERS%ROWTYPE; -- 4. -- Получение имени сотрудника -- по его номеру CURSOR get_name(empl_nm SALESREPS.empl_num%TYPE) RETURN SALESREPS.name%TYPE IS SELECT name FROM SALESREPS WHERE empl_num = empl_nm;
Надеюсь, вы заметили, что курсоры не просто так определены, а выполняют отбор вполне осмысленной информации. Вспомните наши мучения с SELECT, я не даром там распинался. Но те кто его хорошо знают, то же пусть освежат знания. Итак в определенных (явных) курсорах ключевым звеном является оператор SELECT (ДА ОН ВООБЩЕ КЛЮЧЕВОЙ ЗВЕНО ВСЕХ БД. ). Именно он определяет, что будет возвращать курсор после того как вы его откроете. Итак курсор под номером 1. Это простой не параметризованный курсор возвращающий все содержимое таблицы запроса в данном случае ORDERS. Это самый легкий из курсоров! 🙂 Курсор под номером 2. Это более сложный параметризованный курсор с одним параметром, но их может быть и больше. Он возвращает как видно из условия WHERE одну строку, так как поле order_num ключевое! Обратите внимание при передаче параметра использована конструкция %TYPE. Курсор под номером 3. Чуть более расширенная версия предыдущего, кроме того используется конструкция RETURN — с применением переменной записи на базе таблицы ORDERS. Такая конструкция просто возвратит одну полную запись из таблицы ORDERS при открытии курсора. Такие конструкции курсоров мы рассмотрим после того, как разберемся с процедурами и функциями. Курсор 4. Это то же самое, что и курсор 3, но он применяет конструкцию RETURN для того, чтобы вернуть значение одного поля таблицы SALESREPS, обратите внимание на местоположение оператора RETURN, хотя я в своей практике такие «фортели» с курсорами не использовал! 🙂 Но, тем не менее, в документации такое есть и вам будет полезно посмотреть как это выглядит! Вот собственно, так (пока отвлеченно) определяются курсоры. Можете пока все это переварить, так как дальше на вас обрушится еще большее количество информации. 🙂
Курсоры (Cursors)
Курсор – это средство извлечения данных из базы данных Oracle. Курсоры содержат определения столбцов и объектов (таблиц, представлений и т.п.) из которых будут извлекаться данные, а также набор критериев, определяющих какие именно строки должны быть выбраны.
Пользователю доступны следующие способы выполнения запроса к базе данных:
- Неявные курсоры — простой оператор SELECT . INTO извлекает одну строку данных непосредственно в переменные локальной программы. Это удобный (и часто наиболее эффективный) способ доступа к данным, использование которого, однако, может приводить к необходимости повторного кодирования оператора SELECT (или похожих операторов) в нескольких местах программы.
- Явные курсоры — вы можете явно объявить курсов в разделе объявлений (локального блока или пакета). В этом случае курсор можно будет открывать и извлекать данные в одной или нескольких программах, причем возможности контроля будут шире, чем при использовании неявных курсоров.
- Курсорные переменные — дополнительный уровень гибкости обеспечивают курсорные переменные (объявленные на основе типа REF CURSOR), которые позволяют передавать указатель на результирующее множество, полученное по запросу из одной программы в другую. Любая программа, имеющая доступ к такой переменной, сможет открывать и закрывать курсор, а также выбирать из него данные.
- Курсорные выражения — появившиеся в версии Oracle 9i выражения CURSOR преобразуют оператор SELECT в указатель (типа REF CURSOR) на результирующее множество и могут использоваться в сочетании с табличными функциями для повышения прозводительности приложений.
Сравнение явных и неявных курсоров
В PL/SQL неявные курсоры – это курсоры, которые определяются в момент выполнения.
DECLARE V_date DATE; BEGIN SELECT order_date INTO v_date FROM orders WHERE order_number = 100; END;
Явный курсор – это курсор, который определяется до начала выполнения.
DECLARE CURSOR curs_get_od IS SELECT order_date FROM orders WHERE order_number = 100; V_date DATE; BEGIN OPEN cure_get_od; FETCH curs_get_od INTO v_date; CLOSE curs_get_od; END;
Ключевое преимущество явного курсора заключается в наличии у него атрибутов, облегчающих применение условных операторов.
Типичные операции над запросами
Для исполнения оператора SQL внутри программы PL/SQL выполняет одни и те же операции для всех типов курсоров. В одних случаях PL/SQL выполняет их автоматически, а в других (для явных курсоров) программисту необходимо написать соответствующий код.
- Синтаксический анализ — первым этапом обработки оператора SQL является его синтаксический анализ, который проводится для проверки корректности оператора и определения плана его выполнения.
- Связывание — это сопоставление значений из вашей программы (хост-переменных) заполнителям используемого оператора SQL. Для статического SQL такое связывание выполняет само ядро PL/SQL. Для динамического SQL программист, если он планирует использовать переменные связывания, должен явно запросить выполнение этой операции.
- Открытие — при открытии курсора, переменные связывания используются для определения результирующего множества команды SQL. Указатель активной (текущей) строки устанавливается на первой строке. В некоторых случаях явное открытие курсора не требуется; ядро PL/SQL само выполняет эту операцию (например, для неявных курсоров или встроенного динамического SQL).
- Исполнение — на этапе исполнения оператор выполняется внутри ядра SQL.
- Выборка — при выполнении запроса команда FETCH извлекает следующую строку из результирующего множества курсора. При каждой выборке PL/SQL передвигает курсор вреперд на одну строку по результирующему множеству. При работе с явными курсорами следует помнить, что в случае, когда строк для извлечения больше нет, FETCH ничего не делает (не инициирует исключение).
- Закрытие — на этом этапе курсор закрывается, освобождается используемая им память. После закрытия курсор уже не содержит результирующее множество. В некоторых случаях явное закрытие курсора не требуется, ядро PL/SQL само выполняет эту операцию (например, для неявных курсоров или встроенного динамического SQL
Повторное использование курсоров
Скомпилированная версия курсора может использоваться повторно во избежание расходов на разбор и повторную компиляцию.
Полный и частичный разбор
Процесс компиляции нового курсора называется полным разбором. Упрощенно данный процесс может быть представлен четырьмя этапами:
- Проверка – курсор проверяется на соответствие синтаксическим правилам SQL, также проверяются объекты (таблицы и столбцы), на которые он ссылается.
- Компиляция – курсор компилируется в исполняемый код и загружается в разделяемый пул сервера баз данных. Для определения местоположения курсора в разделяемом пуле используется его адрес.
- Вычисление плана выполнения – оптимизатор по стоимости (cost-based optimizer — CBO) Oracle определяет наилучший для данного курсора план выполнения и присоединяет его к курсору.
- Вычисление хеша – ASCII-значения всех символов курсора складываются и передаются в функцию хеширования. Эта функция рассчитывает значение, по которому курсор легко может быть найден при повторном обращении. Данное значение называется хеш-значением курсора.
Чтобы определить, может ли планируемый к выполнению курсор воспользоваться уже скомпилированной версией из разделяемого пула, Oracle применяет сложный алгоритм.
- 1 Рассчитать сумму ASCII – значений всех символов курсора ( исключая переменные связывания).
- 2 Применить алгоритм хеширования к полученной сумме.
- 3 Проверить наличие в разделяемом пуле курсора с таким же значением хеша.
- 4 Если такой курсор найден, он может быть использован повторно.
Tags: Курсоры, Cursors
PL/SQL
tags: Администрирование Oracle DataBase || SQL & PL/SQL
Исходные коды проекта хранятся на github. Можете заводить Issue и Discussions, при необходимости.
Чтобы задать вопрос, добавить свои знания, исправить ошибки и неточности, пишите в телеграм чате.
Курсоры
Курсор можно рассматривать как итератор, специфичный для баз данных.
Запрос исполнился, мы получили какие-то результаты, и теперь собираемся достать множество строк. Все, что обсуждалось до этого (set и select into) позволяло доставать только один результат, а из курсора их можно достать множество.
Объявление курсора
Синтаксис
declare имя -- объявление курсора с именем sensitive|insensitive|asensitive> -- чувствительность курсора [[no] scroll] -- возможность ходить произвольным образом по данным вперед и назад (default - no scroll) cursor select. -- запрос данных, по которым будет ходить курсор [for read only|update [of столбцы]>]; -- права на чтение (дефолтное право) или на обновление (всей таблицы (в частности, этот вариант подходит для удаления) или выбранных столбцов)
Чувствительность курсора
Данные из курсора обрабатываются по одной строке (способа получить более одной строки за один раз нет). Мы напишем цикл, в рамках которого будут выбираться данные из курсора, и возможно будут меняться данные в нашей базе данных. Получаем, что во время таких итераций можно поменять данные самой таблицы, по которой построен текущий курсор. Представим ситуацию, что мы в сделанном курсоре в явной форме написали update на ту таблицу или таблицы, по которым сделан курсор. Что должно произойти в таком случае? В зависимости от желаемого поведения можно выбрать разную чувствительность курсора.
- [math]\mathtt[/math] — курсор, чувствительный к изменениям. Измененные данные можно будет увидеть в курсоре, если эти данные еще не были пройдены. Иначе, если изменённые данные были просмотрены в прошлом и у нас не scrollable курсор, то они не обновятся. В некотором смысле это итерация по реальным данным, динамическая.
- [math]\mathtt[/math] — курсор фиксированных данных. Данные зафиксированы на момент открытия курсора. Никакие изменения данных не будут отображены через курсор. В некотором смысле это итерация по временной копии таблицы.
- [math]\mathtt[/math] — курсор, наиболее предпочтительный для данной СУБД. Связано с различными способами реализациями СУБД: для одних легче реализуем sensitive cursor, а для других — insensitive. Существует два подхода к реализации СУБД: snapshot-based и lock-based, для них либо sensitive, либо insensitive варианты предпочтительны. Ни одна из опций не является дешевой по умолчанию, поэтому и есть значение asensitive: сама СУБД будет решать, какую чувствительность курсора использовать. Для lock-based проще сделать курсор, чувствительный к изменениям, так как для insensitive потребовалось бы дополнительное копирование. Для snapshot-based предпочтительнее insensitive, так как не потребуется специальным образом учитывать обновления.
Если данные во время использования курсора меняться не будут, то чувствительность курсора не важна.
Scrollable | No scroll курсоры
- [math]\mathtt[/math] [math]\mathtt[/math] — по такому курсору можно ходить только по одной записи вперед, как из обычного итератора в Java.
- [math]\mathtt[/math] — по такому курсору можно ходить не только по одной записи вперед, но и вперед, назад, в начало или конец. Такой курсор больше похож на итератор из языка С++.
Примеры
Взятие курсора на чтение для всех студентов, упорядоченных по идентификатору:
declare SCursor cursor select * from Students order by SId;
Взятие курсора с правом на изменение поля SName для студентов группы M3439 в произвольном порядке:
declare SCursor cursor select * from Students where GId = 'M3439' for update of SName;
Открытие и закрытие
Объявление курсора говорит о намерении получения данных. Реальная выборка в момент объявления не производится. Она происходит в момент открытия курсора (выполнения действия open cursor). Если курсор insensitive, то в момент открытия фиксируются данные, которые попадут в курсор.
С курсором ассоциируются множество ресурсов, поэтому их необходимо закрывать. При выходе из блока, в котором был объявлен курсор, он будет автоматически закрыт. Это чем-то напоминает автоматическую сборку ресурсов в sql. При повторном открытии курсора произойдет повторная инициализация, влекущая новое прочтение данных для insensitive курсора.
Синтаксис
open курсор; close курсор;
Получение данных
Для получения данных из курсора есть конструкция fetch.
Синтаксис
fetch [next|prior|last|first|absolute n|relative n] курсор into переменные;
Описание команд
- [math]\mathtt[/math] — получение следующей записи (доступно по умолчанию, все команды ниже доступны только для scroll курсора)
- [math]\mathtt[/math] — предыдущая запись
- [math]\mathtt[/math] — последняя запись
- [math]\mathtt[/math] — первая запись
- [math]\mathtt[/math] [math]\mathtt[/math] — получить запись с номером n от начала
- [math]\mathtt[/math] [math]\mathtt[/math] — запись с номером n, нумерация с текущей позиции (n может быть как положительным (движение в сторону конца), так и отрицательным (в этом случае движение назад))
Отсутствие данных
Если данные закончились, либо при помощи команд выше был осуществлен невалидный переход, то случится событие not found.
Пример
В данном примере из курсора для студентов мы получим идентификатор, имя и фамилию того студента, на которого сейчас указывает курсор.
fetch SCursor into Sid, FirstName, LastName;
Для получения всех данных из курсора, можно создать цикл, предварительно создав обработчик ошибок на not found снаружи цикла, в котором выйдем из цикла, когда все элементы будут обработаны. Состояние sqlstate 02xxx не является исключительной ситуацией, а просто предупреждение от СУБД, которое зачастую игнорируется. Вопрос производительности зависит от реализации СУБД.
Позиционированные изменения
Изменение или удаление ровно одной строчки, которую последней выдал курсор (только в update и delete ).
Синтаксис
update таблица set что where current of курсор; -- изменение ровно одной строки, которую последней выдал курсор delete from таблица where current of курсор; -- удаление последней выданной строки
Пример
if FirstName = 'Иван' then delete from Students where current of SCursor; end if;
В данном примере мы удалим текущего студента, если его имя Иван.
Пример применения курсора
create procedure updateNameStat(name) begin declare cnt int default 0; declare exit handler for sqlstate not found begin insert into Stats (Name, Cnt) values (name, cnt); end; declare SCursor cursor select FirstName from Students; open SCursor; loop declare sname varchar(20); fetch SCursor into sname; if name = sname then set cnt = cnt + 1; end if; end loop; end;
Пояснения
В данном примере объявлен счетчик cnt , по умолчанию проинициализированный 0, курсор SCursor , перебирающий значение столбца FirstName из таблицы Students . Далее в бесконечном цикле (так как мы не имеет возможности написать условие выхода из цикла):
- определяем переменную sname , в которой будем хранить имя студента
- достаем следующую запись в эту переменную (напоминание: fetch по умолчанию — это fetch next )
- проверяем, если текущее имя sname имя соответствует выделенному имени name , то увеличиваем счетчик.
Повторяем данные операции до тех пор, пока у нас не случится not found , при возникновении которого в обработчике not found обновим данные статистики и (по определению обработчика в sql) выйдем из блока, в котором был объявлен handler — то есть в данном случае выйдем из блока процедуры.
Обработчик not found может быть только один. Если бы у нас было несколько курсоров, и мы бы захотели знать в обработчике, в каком из курсоров закончились данные, то предварительно вели бы записи в переменные, из каких курсоров планируем достать данные. И в обработчике проверили бы значение переменных.
Данные пример написан исключительно для демонстрации работы с курсорами. В реальной жизни подобное поведение может быть достигнут проще с использованием select и count .
Примечания
Некоторые базы данных позволяют проверить, есть ли в курсоре еще данные. В этих случаях пишется цикл while с вызовом метода проверки. Однако стандартом наличие этой проверки не предусмотрено.
Особенности курсоров
Курсоры, описанные в данной статье, являются внутренними. Они существуют внутри базы данных, используются, в том числе для взаимодействия между различными частями базы данных при планировании.
Внешние курсоры
Результат запроса к базе данных может быть слишком велик и стать виной нехватки памяти как на стороне клиента, так и на стороны сервера, увеличить нагрузку на сеть, вызывать и другие проблемы. Поэтому наружу данные выдаются в виде внешнего курсора. После исполнения команды select выдается внешний курсор на данные, аналогично внешний курсор выдается при возврате результата из хранимой процедуры.
Размер выборки
Может быть указан для внешнего курсора каким-либо образом (в количестве записей или в объеме данных, который выдается за один раз).
При выдаче курсора приходит метаинформация о курсоре и первая порция данных, размер которой мы указали. Для получения последующих порций данных необходимо обращаться к серверу, что будет медленнее, чем получение первой порции. В конце сервер сообщит о том, что данные закончились, автоматически освободит ресурсы.
- Малый размер выборки — много повторных обращений к серверу базы данных, а так как обычно такое обращение происходит по сети, то взаимодействие не слишком быстрое.
- Большой размер выборки — требуется много памяти, как со стороны сервера для генерации данных, так и со стороны прикладного приложения.
Выдача курсора приводит к расходу ресурсов сервера (память, возможно дисковая память, блокировки и так далее). Поэтому внешний курсор стоит закрыть как можно раньше.
Однако чтобы не получить слишком много данных по запросу, они выдаются в виде внешнего курсора.
Литература
- Дейт К. Введение в системы баз данных (главы 4 и 17)
- Уидом Д., Ульман Д. Основы реляционных баз данных (раздел 7.4)
- Gulutzan P., Pelzer T. SQL-99 complete, really
- Chapter 25 – SQL-Invoked Routine
- Chapter 26 – PSM: Not Just Persistent Stored Modules
Курсоры: принципы работы
Аннотация: Дается определение курсора. Приводится описание его типов и поведения: статические, динамические, последовательные и ключевые курсоры. Описываются принципы управления курсором: создание и открытие курсора, считывание данных, закрытие курсора. Приводятся примеры программирования курсора.
Понятие курсора
Запрос к реляционной базе данных обычно возвращает несколько рядов (записей) данных, но приложение за один раз обрабатывает лишь одну запись . Даже если оно имеет дело одновременно с несколькими рядами (например, выводит данные в форме электронных таблиц), их количество по-прежнему ограничено. Кроме того, при модификации, удалении или добавлении данных рабочей единицей является ряд. В этой ситуации на первый план выступает концепция курсора , и в таком контексте курсор – указатель на ряд.
Курсор в SQL – это область в памяти базы данных, которая предназначена для хранения последнего оператора SQL. Если текущий оператор – запрос к базе данных, в памяти сохраняется и строка данных запроса, называемая текущим значением, или текущей строкой курсора . Указанная область в памяти поименована и доступна для прикладных программ.
Обычно курсоры используются для выбора из базы данных некоторого подмножества хранимой в ней информации. В каждый момент времени прикладной программой может быть проверена одна строка курсора . Курсоры часто применяются в операторах SQL , встроенных в написанные на языках процедурного типа прикладные программы. Некоторые из них неявно создаются сервером базы данных , в то время как другие определяются программистами.
В соответствии со стандартом SQL при работе с курсорами можно выделить следующие основные действия :
- создание или объявление курсора ;
- открытие курсора, т.е. наполнение его данными, которые сохраняются в многоуровневой памяти ;
- выборка из курсора и изменение с его помощью строк данных;
- закрытие курсора , после чего он становится недоступным для пользовательских программ;
- освобождение курсора , т.е. удаление курсора как объекта, поскольку его закрытие необязательно освобождает ассоциированную с ним память.
В разных реализациях определение курсора может иметь некоторые отличия. Так, например, иногда разработчик должен явным образом освободить выделяемую для курсора память . После освобождения курсора ассоциированная с ним память также освобождается. При этом становится возможным повторное использование его имени. В других реализациях при закрытии курсора освобождение памяти происходит неявным образом. Сразу после восстановления она становится доступной для других операций: открытие другого курсора и т.д.
В некоторых случаях применение курсора неизбежно. Однако по возможности этого следует избегать и работать со стандартными командами обработки данных: SELECT , UPDATE , INSERT , DELETE . Помимо того, что курсоры не позволяют проводить операции изменения над всем объемом данных, скорость выполнения операций обработки данных посредством курсора заметно ниже, чем у стандартных средств SQL .
Реализация курсоров в среде MS SQL Server
SQL Server поддерживает три вида курсоров :
- курсоры SQL применяются в основном внутри триггеров, хранимых процедур и сценариев;
- курсоры сервера действуют на сервере и реализуют программный интерфейс приложений для ODBC, OLE DB, DB_Library;
- курсоры клиента реализуются на самом клиенте. Они выбирают весь результирующий набор строк из сервера и сохраняют его локально, что позволяет ускорить операции обработки данных за счет снижения потерь времени на выполнение сетевых операций.
Различные типы многопользовательских приложений требуют и различных типов организации параллельного доступа к данным. Некоторым приложениям необходим немедленный доступ к информации об изменениях в базе данных. Это характерно для систем резервирования билетов. В других случаях, например, в системах статистической отчетности, важна стабильность данных, ведь если они постоянно модифицируются, программы не смогут эффективно отображать информацию. Различным приложениям нужны разные реализации курсоров .
В среде SQL Server типы курсоров различаются по предоставляемым возможностям. Тип курсора определяется на стадии его создания и не может быть изменен. Некоторые типы курсоров могут обнаруживать изменения , сделанные другими пользователями в строках, включенных в результирующий набор. Однако SQL Server отслеживает изменения таких строк только на стадии обращения к строке и не позволяет отслеживать изменения, когда строка уже считана.
Курсоры делятся на две категории: последовательные и прокручиваемые . Последовательные позволяют выбирать данные только в одном направлении – от начала к концу. Прокручиваемые же курсоры предоставляют большую свободу действий – допускается перемещение в обоих направлениях и переход к произвольной строке результирующего набора курсора .Если программа способна модифицировать данные, на которые указывает курсор , он называется прокручиваемым и модифицируемым. Говоря о курсорах , не следует забывать об изолированности транзакций. Когда один пользователь модифицирует запись , другой читает ее при помощи собственного курсора , более того, он может модифицировать ту же запись , что делает необходимым соблюдение целостности данных.
SQL Server поддерживает курсоры статические , динамические , последовательные и управляемые набором ключей.
В схеме со статическим курсором информация читается из базы данных один раз и хранится в виде моментального снимка (по состоянию на некоторый момент времени), поэтому изменения, внесенные в базу данных другим пользователем, не видны. На время открытия курсора сервер устанавливает блокировку на все строки, включенные в его полный результирующий набор. Статический курсор не изменяется после создания и всегда отображает тот набор данных, который существовал на момент его открытия .
Если другие пользователи изменят в исходной таблице включенные в курсор данные, это никак не повлияет на статический курсор .
В статический курсор внести изменения невозможно, поэтому он всегда открывается в режиме «только для чтения».
Динамический курсор поддерживает данные в «живом» состоянии, но это требует затрат сетевых и программных ресурсов. При использовании динамических курсоров не создается полная копия исходных данных, а выполняется динамическая выборка из исходных таблиц только при обращении пользователя к тем или иным данным. На время выборки сервер блокирует строки, а все изменения , вносимые пользователем в полный результирующий набор курсора , будут видны в курсоре . Однако если другой пользователь внес изменения уже после выборки данных курсором , то они не отразятся в курсоре .
Курсор, управляемый набором ключей , находится посередине между этими крайностями. Записи идентифицируются на момент выборки, и тем самым отслеживаются изменения . Такой тип курсора полезен при реализации прокрутки назад – тогда добавления и удаления рядов не видны, пока информация не обновится, а драйвер выбирает новую версию записи, если в нее были внесены изменения .
Последовательные курсоры не разрешают выполнять выборку данных в обратном направлении. Пользователь может выбирать строки только от начала к концу курсора . Последовательный курсор не хранит набор всех строк. Они считываются из базы данных , как только выбираются в курсоре , что позволяет динамически отражать все изменения , вносимые пользователями в базу данных с помощью команд INSERT , UPDATE , DELETE . В курсоре видно самое последнее состояние данных.
Статические курсоры обеспечивают стабильный взгляд на данные. Они хороши для систем «складирования» информации: приложений для систем отчетности или для статистических и аналитических целей. Кроме того, статический курсор лучше других справляется с выборкой большого количества данных. Напротив, в системах электронных покупок или резервирования билетов необходимо динамическое восприятие обновляемой информации по мере внесения изменений. В таких случаях используется динамический курсор . В этих приложениях объем передаваемых данных, как правило, невелик, а доступ к ним осуществляется на уровне рядов (отдельных записей). Групповой доступ встречается очень редко.
