Опубликован: 20.12.2005 | Уровень: специалист | Доступ: платный | ВУЗ: Московский государственный университет имени М.В.Ломоносова
Лекция 6:

Применение курсоров

< Лекция 5 || Лекция 6: 1234 || Лекция 7 >

Извлечение данных

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

При использовании перемещаемого курсора после создания результирующего набора позицию курсора можно перемещать. Это можно выполнять непосредственно функцией выборки данных 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, и удаляет указанную строку

Массив состояния строк

Массив состояния строк указывается атрибутом оператора SQL_ATTR_ROW_STATUS_PTR. Он содержит значения состояния каждой строки результирующего набора. Состояние строки устанавливается драйвером после вызова одной из следующих функций: SQLFetch, SQLFetchScroll, SQLBulkOperations, SQLSetPos.

Массив операций над строками

Функции ODBC API позволяют выполнять одновременно (за один вызов функции) некоторую операцию над несколькими строками. Такие операции называются множественными операциями.

Массив операций над строками указывается атрибутом оператора SQL_ATTR_ROW_OPERATION_PTR. Каждый элемент массива может иметь одно из следующих значений:

  • SQL_ROW_PROCEED - строка должна быть обработана (по умолчанию);
  • SQL_ROW_IGNORE - игнорировать данную строку.

Массив операций над строками определяет, будет ли вызов функции SQLSetPos для множественной операции (bulk operation) выполняться или игнорироваться.

Применение функции SQLSetPos

При изменении данных перед вызовом функции SQLSetPos следует:

  1. Вызвать функцию SQLBindCol (или SQLSetDescRec ) для каждого столбца, определив тип данных, буфер для данных и его размер. Если для столбца не назначается связываемый с ним буфер, то данные могут быть переданы последовательностью вызовов функции SQLPutData. Такие столбцы называются столбцами времени выполнения (data-at-execution columns).
  2. Для гарантии того, что изменяемый столбец может быть изменен, следует вызвать функцию SQLColAttribute.
  3. Для создания результирующего набора можно выполнить функцию SQLExecDirect или SQLExecute.
  4. Для выборки данных использовать функции SQLFetch или SQLFetchScroll.
< Лекция 5 || Лекция 6: 1234 || Лекция 7 >
Михаил Трифонов
Михаил Трифонов
Россия, Ленинград, ЛГМИ Ленинградский Гидрометеорологический Институт, 1986
миха Трохимчук
миха Трохимчук
Россия