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

       

Изменение позиции курсора


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

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

Для изменения или удаления любой строки из набора строк можно использовать функцию SQLSetPos. Применение функции SQLSetPos является удобной альтернативой выполнения отдельного SQL-оператора. Так, это позволяет ODBC-драйверу поддерживать позиционированное изменение даже в том случае, если сам источник данных не поддерживает позиционированный UPDATE в SQL-операторе.

Функция SQLSetPos оперирует с текущим набором строк (rowset), который создается после вызова функции SQLFetchScroll, выполняющей извлечение этого набора строк из результирующего набора, сформированного, в свою очередь, при выполнении SQL-оператора.

Функция SQLSetPos имеет следующее формальное описание:

SQLSetPos( SQLHSTMT StatementHandle, SQLUSMALLINT RowNumber, SQLUSMALLINT Operation, SQLUSMALLINT LockType);

Параметр StatementHandle ([Input]) указывает дескриптор оператора. Параметр RowNumber ([Input]) определяет позицию строки в наборе строк, над которой выполняется операция, указываемая параметром Operation. Если значение параметра RowNumber равно 0, то операция будет выполняться над каждой строкой набора строк (которая отмечена соответствующим образом в массиве операций над строками).

Параметр Operation ([Input]) определяет тип выполняемой операции и указывается следующими значениями:

SQL_POSITION SQL_REFRESH SQL_UPDATE SQL_DELETE

Отметим, что значение параметра Operation, равное SQL_ADD, начиная с версии ODBC 3.x, отменено. Однако драйверы ODBC 3.x в целях обратной совместимости поддерживают эту возможность, заменяя вызов функции SQLSetPos с данным значением параметра на вызов функции SQLBulkOperations со значением параметра Operation, равным SQL_ADD.
Обратно, если приложение ODBC 3.x использует драйвер ODBC 2.x, то менеджер драйверов заменяет для параметра, равного SQL_ADD, вызов SQLBulkOperations на вызов SQLSetPos.

Параметр LockType ([Input]) определяет уровень блокировки строки при выполнении операции, указываемой параметром Operation, и может принимать следующие значения:

  • SQL_LOCK_NO_CHANGE - состояние блокировки строки не должно измениться после выполнения функции;
  • SQL_LOCK_EXCLUSIVE - выполняется блокировка строки с эксклюзивным доступом. Это гарантирует, что другое приложение не сможет получить доступ к данной строке;
  • SQL_LOCK_UNLOCK - выполняется освобождение строки.


Строка, заблокированная при выполнении функции SQLSetPos, остается заблокированной до тех пор, пока приложение не вызовет эту же функцию со значением параметра LockType, равным SQL_LOCK_UNLOCK, или функцию SQLFreeHandle для дескриптора оператора, или функцию SQLFreeStmt с опцией SQL_CLOSE. Если драйвер поддерживает транзакции, то строка, заблокированная при выполнении функции SQLSetPos, освобождается при завершении транзакции функцией SQLEndTran (как при коммите, так и при откате транзакции) в том случае, если при завершении транзакции установлено закрытие курсора.

При выполнении операций SQL_DELETE и SQL_UPDATE изменяется состояние строки. Так, в массиве состояния строк, указатель на который определяется атрибутом оператора SQL_ATTR_ROW_STATUS, все удаленные строки будут отмечены как SQL_ROW_DELETED.

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

SQL_DYNAMIC_CURSOR_ATTRIBUTES1, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, SQL_KEYSET_CURSOR_ATTRIBUTES1, SQL_STATIC_CURSOR_ATTRIBUTES1.

В следующей таблице приведено описание операций, которые могут быть выполнены функцией SQLSetPos

Значение параметра OperationОписание
SQL_POSITIONПозиция курсора устанавливается на строку с номером, указанным параметром RowNumber (нумерация начинается с 1)
SQL_REFRESHПозиция курсора устанавливается на строку с номером, указанным параметром RowNumber, и драйвер обновляет данные для этой строки в буфере результирующего набора. При этом функция SQLSetPos выполняет обновление содержания и состояния строк в текущем сформированном результирующем наборе: данные в буфере обновляются, а не повторно извлекаются. В отличие от функции SQLSetPos функция SQLFetchScroll с значениями параметров FetchOrientation, равным SQL_FETCH_RELATIVE, и RowNumber, равным 0, выполняет повторное извлечение строк из результирующего набора (при этом, если драйвер допускает, то для обновляемого курсора будут отображаться добавленные строки и не отображаться - удаленные). Успешное выполнение функцией SQLSetPos обновления строки не изменяет состояния строки, равного SQL_ROW_DELETED, а состояние строки, равное SQL_ROW_ADDED, заменяет на SQL_ROW_SUCCESS (в том случае, если массив состояний строк существует). В том случае, если курсор был открыт с атрибутом оператора SQL_ATTR_CONCURRENCY SQL_CONCUR_ROWVER или SQL_CONCUR_VALUES, то в случае операции обновления, выполняемой функцией SQLSetPos, может быть определено, что строки были изменены: при этом буфер результирующего набора обновляется при извлечении строки с сервера
SQL_UPDATEУстанавливает позицию курсора на строку, указанную параметром RowNumber, и изменяет значения строки, беря их из буфера (буферов результирующего набора), определенного параметром TargetValuePtr функции SQLBindCol
SQL_DELETEУстанавливает позицию курсора на строку, определенную параметром RowNumber, и удаляет указанную строку

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