Реализации курсоров

Microsoft SQL Server поддерживает три способа реализации курсоров:

  • Курсоры Transact-SQL
    Основываются на синтаксисе DECLARE CURSOR и используются главным образом в сценариях Transact-SQL, хранимых процедурах и триггерах. Курсоры Transact-SQL реализуются на сервере и управляются инструкциями Transact-SQL, направляемыми клиентом серверу. Они также могут содержаться в пакетах, хранимых процедурах или триггерах.

  • Серверные курсоры интерфейса прикладного программирования (API)
    Поддерживают функции курсоров API в OLE DB и ODBC. Курсоры API реализуются на сервере. Всякий раз, когда клиентское приложение вызывает функцию курсора API, поставщик OLE DB или драйвер ODBC для собственного клиента SQL Server передает требование на сервер для выполнения действия в отношении серверного курсора API.

  • Клиентские курсоры
    Реализуются внутренне драйвером ODBC для собственного клиента SQL Server и DLL, реализующим API-интерфейс ADO. Клиентские курсоры реализуются посредством кэширования всех строк результирующего набора на клиенте. Каждый раз, когда клиентское приложение вызывает функцию курсора API, драйвер ODBC для собственного клиента SQL Server или ADO DLL выполняет операцию курсора на строках результирующего набора, кэшированных на клиенте.

Поскольку курсоры Transact-SQL и серверные курсоры API реализуются на сервере, они собирательно называются серверными курсорами.

Не следует смешивать использование этих различных типов курсоров. При выполнении инструкции DECLARE CURSOR с ключевым словом OPEN из приложения сначала необходимо присвоить атрибутам курсора API их значения по умолчанию. Если присвоить атрибутам курсора API значения, отличные от их значений по умолчанию, а затем выполнить инструкцию DECLARE CURSOR с ключевым словом OPEN, это рассматривается как требование к SQL Server установить соответствие курсора API и курсора Transact-SQL. Например, нельзя определить значения атрибутов ODBC, требующих сопоставления курсора, управляемого набором ключей, с результирующим набором, а затем использовать эту инструкцию для выполнения вызова инструкции DECLARE CURSOR с ключевым словом OPEN для курсора INSENSITIVE.

Возможным недостатком серверных курсоров является то, что они в настоящее время поддерживают не все инструкции Transact-SQL. Серверные курсоры не поддерживают инструкции Transact-SQL, создающие несколько результирующих наборов; следовательно, они не могут быть использованы при выполнении приложением хранимой процедуры или пакета, содержащих более одной инструкции SELECT. Серверные курсоры также не поддерживают инструкции SQL, содержащие ключевые слова COMPUTE, COMPUTE BY, FOR BROWSE или INTO.

Серверные курсоры в сопоставлении с результирующими наборами по умолчанию

Использование курсора менее эффективно, чем использование результирующего набора по умолчанию. В случае с результирующим набором по умолчанию единственным пакетом, направляемым от клиента серверу, является пакет, содержащий инструкцию для выполнения. При использовании серверного курсора каждая инструкция FETCH должна быть отправлена от клиента серверу, где она должна быть подвергнута синтаксическому анализу и скомпилирована в план выполнения.

Если инструкция Transact-SQL должна возвратить относительно небольшой результирующий набор, который может быть кэширован в памяти, доступной клиентскому приложению, и еще до выполнения инструкции известно, что необходимо получить весь результирующий набор, то следует использовать результирующий набор по умолчанию. Используйте серверные курсоры только в тех случаях, когда операции курсоров требуются для поддержки функциональных возможностей приложения или если предполагается получение только части результирующего набора.

Серверные курсоры в сопоставлении с клиентскими курсорами

Существует несколько преимуществ в использовании серверных курсоров вместо клиентских курсоров:

  • Производительность

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

  • Дополнительные типы курсоров

    Если драйвер ODBC для собственного клиента SQL Server использовал только клиентские курсоры, он может поддерживать только однонаправленные и статические курсоры. Используя серверные курсоры API, драйвер может также поддерживать управляемые набором ключей и динамические курсоры. Кроме того, SQL Server поддерживает весь диапазон атрибутов параллелизма курсоров только через серверные курсоры. Клиентские курсоры ограничены в поддерживаемых ими функциональных возможностях.

  • Более точные позиционированные обновления

    Серверные курсоры непосредственно поддерживают позиционированные операции, например функцию ODBC SQLSetPos или инструкции UPDATE и DELETE с предложением WHERE CURRENT OF. Клиентские курсоры, с другой стороны, имитируют позиционированные обновления курсора, создавая инструкцию Transact-SQL UPDATE, что приводит к непреднамеренным обновлениям, если более одной строки удовлетворяют условиям предложения WHERE инструкции UPDATE.

  • Использование памяти

    При использовании серверных курсоров клиенту не требуется кэшировать большие объемы данных или следить за положением курсора, поскольку этим занимается сервер.

  • Множественные активные инструкции

    При использовании серверных курсоров результаты не остаются в ожидании на связи между операциями курсора. Это позволяет выполнять одновременно несколько основанных на курсоре инструкций.

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