Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску

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

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

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

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

Использование [ править ]

Чтобы использовать курсоры в процедурах SQL, вам необходимо сделать следующее:

  1. Объявите курсор, определяющий набор результатов.
  2. Откройте курсор, чтобы установить набор результатов.
  3. При необходимости извлекайте данные из курсора в локальные переменные, по одной строке за раз.
  4. Когда закончите, закройте курсор.

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

В этом разделе представлены способы, которыми стандарт SQL: 2003 определяет, как использовать курсоры в приложениях со встроенным SQL. Не все привязки приложений для систем реляционных баз данных соответствуют этому стандарту, а некоторые (например, CLI или JDBC ) используют другой интерфейс.

Программист сообщает СУБД о курсоре с помощью оператора DECLARE... CURSORи присвоения курсору (обязательного) имени:

ОБЪЯВИТЬ имя_курсора КУРСОР ВЫБРАН ... ИЗ ...

Прежде чем код сможет получить доступ к данным, он должен открыть курсор с OPENоператором. Сразу после успешного открытия курсор располагается перед первой строкой в ​​наборе результатов.

ОТКРЫТЬ имя_курсора

Приложения помещают курсоры в определенную строку в наборе результатов с FETCHоператором. Операция выборки передает данные строки в приложение.

FETCH имя_курсора INTO ...

После того, как приложение обработало все доступные строки или операция выборки должна быть помещена в несуществующую строку (сравните прокручиваемые курсоры ниже), СУБД возвращает SQLSTATE '02000' (обычно сопровождаемый SQLCODE +100), чтобы указать конец набора результатов.

Последний шаг включает закрытие курсора с помощью CLOSEоператора:

ЗАКРЫТЬ имя_курсора

После закрытия курсора программа может открыть его снова, что означает, что СУБД повторно оценивает тот же или другой запрос и создает новый набор результатов.

Прокручиваемые курсоры [ править ]

Программисты могут объявлять курсоры как прокручиваемые или не прокручиваемые. Возможность прокрутки указывает направление, в котором может перемещаться курсор.

С помощью курсора без возможности прокрутки (или курсора только вперед ) вы можете FETCHкаждую строку не более одного раза, и курсор автоматически перемещается к следующей строке. После получения последней строки, если вы выполните выборку снова, вы поместите курсор после последней строки и получите следующий код: SQLSTATE 02000 (SQLCODE +100).

Программа может позиционировать прокручиваемый курсор в любом месте результирующего набора с помощью FETCHоператора SQL. При объявлении курсора необходимо указать ключевое слово SCROLL. По умолчанию это NO SCROLL, хотя разные языковые привязки, такие как JDBC, могут применять другое значение по умолчанию.

DECLARE cursor_name  чувствительность  SCROLL CURSOR FOR SELECT ... FROM ...

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

ПОИСК [СЛЕДУЮЩИЙ | ПРИОР | ПЕРВЫЙ | LAST] FROM имя_курсора
ПОЛУЧИТЬ АБСОЛЮТНОЕ n ИЗ имя_курсора
ПОЛУЧИТЬ ОТНОСИТЕЛЬНЫЙ n ОТ имя_курсора ;

Прокручиваемые курсоры потенциально могут обращаться к одной и той же строке в наборе результатов несколько раз. Таким образом, модификации данных (операции вставки, обновления, удаления) из других транзакций могут повлиять на набор результатов. Курсор может быть ЧУВСТВИТЕЛЬНЫМ или НЕДОСТУПНЫМ к таким изменениям данных. Чувствительный курсор улавливает изменения данных, влияющие на результирующий набор курсора, а нечувствительный курсор - нет. Кроме того, курсор может быть INSENSITIVE, и в этом случае СУБД пытается максимально применить чувствительность.

"С УДЕРЖИВАНИЕМ" [ править ]

Курсоры обычно закрываются автоматически в конце транзакции, т. Е. Когда происходит COMMIT или ROLLBACK (или неявное завершение транзакции). Это поведение можно изменить, если курсор объявлен с использованием предложения WITH HOLD (по умолчанию - WITHOUT HOLD). Удерживаемый курсор остается открытым при выполнении COMMIT и закрывается при ROLLBACK. (Некоторые СУБД отклоняются от этого стандартного поведения и также оставляют удерживаемые курсоры открытыми при ROLLBACK.)

ОБЪЯВИТЕ имя_курсора КУРСОР С УДЕРЖАНИЕМ ДЛЯ ВЫБРАТЬ .... ИЗ ....

Когда происходит COMMIT, удерживаемый курсор помещается перед следующей строкой. Таким образом, позиционированный оператор UPDATE или позиционированный оператор DELETE будет успешным только после того, как операция FETCH будет выполнена первой в транзакции.

Обратите внимание, что JDBC определяет курсоры как удерживаемые по умолчанию. Это сделано потому, что JDBC также активирует автоматическую фиксацию по умолчанию.

Позиционированные операторы обновления / удаления [ править ]

Курсоры можно использовать не только для извлечения данных из СУБД в приложение, но и для идентификации строки в таблице, которую необходимо обновить или удалить. Стандарт SQL: 2003 определяет для этой цели операторы SQL с позиционированием обновления и удаления с позиционированием. В таких операторах не используется обычное предложение WHERE с предикатами. Вместо этого курсор определяет строку. Курсор должен быть открыт и уже помещен в строку с помощью FETCHоператора.

ОБНОВЛЕНИЕ table_name НАБОР ... ГДЕ ТЕКУЩИЙ  ИМЯ_КУРСОРА
 УДАЛИТЬ FROM table_name ГДЕ ТЕКУЩИЙ OF  имя_курсора

Курсор должен работать с обновляемым набором результатов, чтобы успешно выполнить позиционированный оператор обновления или удаления. В противном случае СУБД не знала бы, как применить изменения данных к базовым таблицам, указанным в курсоре.

Курсоры в распределенных транзакциях [ править ]

Использование курсоров в распределенных транзакциях ( среды X / Open XA ), которые управляются с помощью монитора транзакций, ничем не отличается от курсоров в нераспределенных транзакциях.

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

Курсоры в XQuery [ править ]

Язык XQuery позволяет создавать курсоры с помощью функции subsquence () .

Формат:

пусть  $ отображается-последовательность  : =  подпоследовательность ( $ результат ,  $ начало ,  $ количество элементов )

Где $ result - это результат начального XQuery, $ start - это номер элемента для запуска, а $ item-count - это количество элементов для возврата.

Точно так же это можно сделать с помощью предиката:

пусть  $ отображается-последовательность  : =  $ результат [от $ начала  до  $ конца ]

Где $endконец последовательности.

Полные примеры см. В XQuery / Searching, Paging and Sorting # Paging в Викиучебнике.

Недостатки курсоров [ править ]

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

Выборка строки из курсора может каждый раз приводить к круговому обходу сети . При этом используется гораздо большая пропускная способность сети, чем обычно требуется для выполнения одного оператора SQL, такого как DELETE. Повторяющиеся обходы сети могут значительно снизить скорость операции с использованием курсора. Некоторые СУБД пытаются уменьшить этот эффект, используя блочную выборку. Блочная выборка подразумевает, что несколько строк отправляются вместе с сервера на клиент. Клиент сохраняет целый блок строк в локальном буфере и извлекает оттуда строки до тех пор, пока этот буфер не будет исчерпан.

Курсоры распределяют ресурсы на сервере, такие как блокировки , пакеты, процессы и временное хранилище. Например, Microsoft SQL Server реализует курсоры, создав временную таблицу и заполняя ее набором результатов запроса. Если курсор не закрыт ( освобожден ) должным образом , ресурсы не будут освобождены до закрытия самого сеанса SQL (соединения). Такая трата ресурсов на сервере может привести к снижению производительности и сбоям.

Пример [ править ]

ТАБЛИЦА СОТРУДНИКОВ

SQL >  desc  EMPLOYEES_DETAILS ; Имя Null? Тип ----------------------------------------- -------- --------------------EMPLOYEE_ID NOT NULL , НОМЕР (6) FIRST_NAME VARCHAR2 (20) LAST_NAME NOT NULL VARCHAR2 (25) ВЕБСАЙТОМ NOT NULL VARCHAR2 (30) PHONE_NUMBER VARCHAR2 (20) hire_date NOT NULL ДАТА JOB_ID NOT NULL VARCHAR2 (10) ЗАРПЛАТА НОМЕР (8,2) COMMISSION_PCT НОМЕР (2,2) НОМЕР MANAGER_ID (6) НОМЕР DEPARTMENT_ID (4)
ОБРАЗЕЦ  КУРСОРА,  ИЗВЕСТНЫЙ  КАК  EECREATE  ИЛИ  ЗАМЕНА  ПРОЦЕДУРА  ЕЕ  КАК НАЧАТЬDECLARE v_employeeID  EMPLOYEES_DETAILS . EMPLOYEE_ID % TYPE ; v_FirstName  EMPLOYEES_DETAILS . FIRST_NAME % TYPE ; v_LASTName  EMPLOYEES_DETAILS . LAST_NAME % TYPE ; v_JOB_ID  EMPLOYEES_DETAILS . JOB_ID % TYPE : =  'IT_PROG' ;Курсор  c_EMPLOYEES_DETAILS  IS SELECT  EMPLOYEE_ID ,  FIRST_NAME ,  LAST_NAME FROM  EMPLOYEES_DETAILS WHERE  JOB_ID  = 'v_JOB_ID' ;НАЧАТЬ ОТКРЫТЫЕ  c_EMPLOYEES_DETAILS ;ПЕТЛЯFETCH  c_EMPLOYEES_DETAILS  INTO  v_employeeID , v_FirstName , v_LASTName ;DBMS_OUTPUT . put_line ( v_employeeID ); DBMS_OUTPUT . put_line ( v_FirstName ); DBMS_OUTPUT . put_line ( v_LASTName );ВЫЙТИ,  КОГДА  c_EMPLOYEES_DETAILS % NOTFOUND ; КОНЕЦ  ПЕТЛИ ;ЗАКРЫТЬ  c_EMPLOYEES_DETAILS ; КОНЕЦ ;КОНЕЦ ;

См. Также [ править ]

  • Итератор
  • Проблемы SQL, требующие курсоров

Ссылки [ править ]

  • Кристофер Дж. Дэйт : Подробная база данных , O'Reilly & Associates, ISBN  0-596-10012-4
  • Томас М. Коннолли , Кэролайн Э. Бегг : системы баз данных , Addison-Wesley, ISBN 0-321-21025-5 
  • Рамиз Эльмасри , Шамкант Б. Нават : основы систем баз данных , Addison-Wesley, ISBN 0-201-54263-3 
  • Нил Мэтью , Ричард Стоунз : Начало баз данных с PostgreSQL: от новичка до профессионала , Apress, ISBN 1-59059-478-9 
  • Томас Кайт : эксперт один на один: Oracle , Apress, ISBN 1-59059-525-4 
  • Кевин Лони: Oracle Database 10g: полный справочник , Oracle Press, ISBN 0-07-225351-7 

Внешние ссылки [ править ]

  • Описания из Портлендского репозитория паттернов
  • Справочное руководство Berkeley DB: Операции с курсорами
  • Курсоры PostgreSQL
  • Документация по курсору MySQL
  • Документация по курсорам FirebirdSQL