Основы проектирования приложений баз данных

       

Управление поведением курсора


Приложение, использующее функции ODBC API, управляет поведением курсора, устанавливая атрибуты оператора. Можно использовать два различных способа определения характеристик курсора:

  • определить тип курсора;
  • определить поведение курсора.

Для определения типа курсора вызывается функция SQLSetStmtAttr со значением атрибута SQL_ATTR_CURSOR_TYPE, который имеет тип SQLUINTEGER и может задаваться следующими значениями:

  • SQL_CURSOR_FORWARD_ONLY - однонаправленный курсор;
  • SQL_CURSOR_STATIC - статический курсор, определяющий, что информация, извлеченная в результирующий набор, не будет отражать изменение данных в БД, произошедшее после создания результирующего набора;
  • SQL_CURSOR_KEYSET_DRIVEN - курсор, управляемый ключом. Такой курсор позволяет "видеть" изменение и удаление строк в БД, произошедшие после создания результирующего набора, но не отображает создание новых строк. Количество строк, для которых создаются ключи, указывается атрибутом SQL_ATTR_KEYSET_SIZE;
  • SQL_CURSOR_DYNAMIC - динамический курсор, отражающий изменение данных в БД после создания результирующего набора.

На используемый тип курсора накладывает ограничение применяемый ODBC-драйвер. Так, многие драйверы не поддерживают возможность применения динамического курсора. В том случае, если при вызове функции SQLSetStmtAttr был указан недопустимый тип курсора, то драйвер заменит его на наиболее подходящий из поддерживаемых типов, а функция вернет код ответа SQLSTATE 01S02 (Опция была изменена).

Для определения поведения курсора вызывается функция SQLSetStmtAttr со значениями атрибутов SQL_ATTR_CURSOR_SCROLLABLE и SQL_ATTR_CURSOR_SENSITIVITY. Смысл этих атрибутов соответствует применению ключевых слов SCROLL и SENSITIVE в SQL-операторе DECLARE CURSOR в стандарте SQL-92.

Атрибут SQL_ATTR_CURSOR_SCROLLABLE управляет перемещаемым курсором, имеет тип SQLUINTEGER и может задаваться следующими двумя значениями:

  • SQL_NONSCROLLABLE - перемещаемый курсор, реализуется как простой однонаправленный курсор. При вызове в приложении функции SQLFetchScroll параметр FetchOrientation может принимать только значение SQL_FETCH_NEXT.
  • SQL_SCROLLABLE - перемещаемый курсор, поддерживающий двунаправленный просмотр результирующего набора, а также прямую выборку строк.


Перемещаемые курсоры для извлечения данных используют функцию SQLFetchScroll (в версии ODBC 2.x использовалась функция SQLExtendedFetched). Если простой однонаправленный курсор, используемый функцией SQLFetch, позволяет перемещаться только в одном прямом направлении и выполнять выборку только одной строки за один вызов функции, то перемещаемый курсор позволяет:

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


Атрибут SQL_ATTR_CURSOR_SENSITIVITY определяет чувствительность курсора к изменениям, выполняемым другими курсорами, имеет тип SQLUINTEGER и может определять режимы, задаваемые следующими значениями:

  • SQL_UNSPECIFIED - неопределенный курсор, при котором изменения могут быть сделаны как видимыми, так и невидимыми или частично видимыми. Этот режим используется по умолчанию;
  • SQL_INSENSITIVE - режим нечувствительного курсора, при котором все курсоры показывают результирующий набор без отражения изменений, выполненных для других курсоров. Нечуствительный курсор является курсором "только чтение". Он соответствует статическому типу курсора с уровнем изоляции "только чтение";
  • SQL_SENSITIVE - режим чувствительного курсора, при котором курсоры "видят" все изменения, выполненные другими курсорами.


Приложение может определять характеристики курсора двояко: или как тип курсора, или как поведение курсора. При этом ODBC-драйвер неявным образом приводит в соответствие значение остальных атрибутов оператора. Следующая таблица иллюстрирует соответствие атрибутов оператора.

Атрибуты, устанавливаемые вызовом функции SQLSetStmtAttrАтрибуты, устанавливаемые драйвером неявно для соответствия характеристик курсора
SQL_ATTR_CONCURRENCY установлен как SQL_CONCUR_READ_ONLYSQL_ATTR_CURSOR_SENSITIVITY получает значение SQL_INSENSITIVE
SQL_ATTR_CONCURRENCY установлен как SQL_CONCUR_LOCK, SQL_CONCUR_ROWVER или SQL_CONCUR_VALUESSQL_ATTR_CURSOR_SENSITIVITY получает значение SQL_UNSPECIFIED или SQL_SENSITIVE, что определяется драйвером. Значение SQL_INSENSITIVE никогда не будет назначено данному атрибуту, так как оно предусматривает режим "только чтение"
SQL_ATTR_CURSOR_SCROLLABLE установлен как SQL_NONSCROLLABLESQL_ATTR_CURSOR_TYPE получает значение SQL_CURSOR_FORWARD_ONLY
SQL_ATTR_CURSOR_SCROLLABLE установлен как SQL_SCROLLABLESQL_ATTR_CURSOR_TYPE получает значение SQL_CURSOR_STATIC, SQL_CURSOR_KEYSET_DRIVEN или SQL_CURSOR_DYNAMIC, что определяется драйвером. Значение SQL_CURSOR_FORWARD_ONLY никогда не будет назначено данному атрибуту
SQL_ATTR_CURSOR_SENSITIVITY установлен как SQL_INSENSITIVESQL_ATTR_CONCURRENCY получает значение SQL_CONCUR_READ_ONLY. SQL_ATTR_CURSOR_TYPE получает значение SQL_CURSOR_STATIC
SQL_ATTR_CURSOR_SENSITIVITY установлен как SQL_SENSITIVESQL_ATTR_CONCURRENCY получает значение SQL_CONCUR_LOCK, SQL_CONCUR_ROWVER или SQL_CONCUR_VALUES ( как определено драйвером). Атрибут SQL_ATTR_CONCURRENCY никогда не получает значение SQL_CONCUR_READ_ONLY. SQL_ATTR_CURSOR_TYPE получает значение SQL_CURSOR_FORWARD_ONLY, SQL_CURSOR_STATIC, SQL_CURSOR_KEYSET_DRIVEN или SQL_CURSOR_DYNAMIC (как определяется драйвером) SQL_ATTR_CURSOR_SENSITIVITY установлен как SQL_UNSPECIFIED SQL_ATTR_CONCURRENCY получает значение SQL_CONCUR_READ_ONLY, SQL_CONCUR_LOCK, SQL_CONCUR_ROWVER или SQL_CONCUR_VALUES ( как определено драйвером). SQL_ATTR_CURSOR_TYPE получает значение SQL_CURSOR_FORWARD_ONLY, SQL_CURSOR_STATIC, SQL_CURSOR_KEYSET_DRIVEN или SQL_CURSOR_DYNAMIC ( как определено драйвером)
SQL_ATTR_CURSOR_TYPE установлен как SQL_CURSOR_DYNAMICSQL_ATTR_SCROLLABLE получает значение SQL_SCROLLABLE. SQL_ATTR_CURSOR_SENSITIVITY получает значение SQL_SENSITIVE. (Только в том случае, если атрибут SQL_ATTR_CONCURRENCY не равен SQL_CONCUR_READ_ONLY. Обновляемые динамические курсоры всегда "видят" все изменения, сделанные в их собственной транзакции
SQL_ATTR_CURSOR_TYPE установлен как SQL_CURSOR_FORWARD_ONLYSQL_ATTR_CURSOR_SCROLLABLE получает значение SQL_NONSCROLLABLE
SQL_ATTR_CURSOR_TYPE установлен как SQL_CURSOR_KEYSET_DRIVENSQL_ATTR_SCROLLABLE получает значение SQL_SCROLLABLE. SQL_ATTR_SENSITIVITY получает значение SQL_UNSPECIFIED или SQL_SENSITIVE (в соответствии с тем, как определяется драйвером, но если атрибут SQL_ATTR_CONCURRENCY не равен SQL_CONCUR_READ_ONLY)
SQL_ATTR_CURSOR_TYPE установлен как SQL_CURSOR_STATICSQL_ATTR_SCROLLABLE получает значение SQL_SCROLLABLE. SQL_ATTR_SENSITIVITY получает значение SQL_INSENSITIVE (в том случае, если атрибут SQL_ATTR_CONCURRENCY равен SQL_CONCUR_READ_ONLY). SQL_ATTR_SENSITIVITY получает значение SQL_UNSPECIFIED или SQL_SENSITIVE (в том случае, если атрибут SQL_ATTR_CONCURRENCY не равен SQL_CONCUR_READ_ONLY)
Функция SQLSetStmtAttr позволяет установить значения атрибутов оператора и имеет следующее формальное описание:

SQLRETURN SQLSetStmtAttr( SQLHSTMT StatementHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength);

Параметр StatementHandle ([Input]) указывает дескриптор оператора.

Параметр Attribute ([Input]) определяет атрибут, значение которого устанавливается, а параметр ValuePtr ([Input]) является указателем на значение, назначаемое атрибуту Attribute.

Параметр StringLength ([Input]) зависит от типа значения, передаваемого параметром ValuePtr, и от вида атрибута (ODBC-определяемый или определяемый драйвером) и может содержать длину строки, игнорироваться или указываться константами, такими как SQL_NTS, SQL_IS_POINTER.


Содержание раздела