Курсоры (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 Если такой курсор найден, он может быть использован повторно.