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

       

Выполнение множественных операций


Множественная операция выполняется функцией SQLSetPos в том случае, если параметр RowNumber равен 0. Она выполняется для всех строк, у которых в массиве операций над строками установлено значение SQL_ROW_PROCEED.

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

Это может быть выполнено вызовом функции SQLSetStmtAttr для установки атрибута оператора SQL_ATTR_ROW_OPERATION_PTR, указывающего на массив элементов типа SQLUSMALLINT. Это поле также может быть установлено вызовом функции SQLSetDescField для определения SQL_DESC_ARRAY_STATUS_PTR.

При множественных операциях игнорировать можно не только обработку строк, но и обработку столбцов (например, столбцов "только для чтения"). Для этого в функции SQLBindCol игнорируемый столбец следует пометить как SQL_COLUMN_IGNORE.

Следующий пример иллюстрирует применение функции SQLSetPos.

#define ROWS 20 // Число строк // в результирующем наборе #define STATUS_LEN 6

SQLCHAR szStatus[ROWS][STATUS_LEN], szReply[3]; SQLINTEGER cbStatus[ROWS], cbID; SQLUSMALLINT rgfRowStatus[ROWS]; SQLUINTEGER sID, crow = ROWS, irow; SQLHSTMT hstmtS, hstmtU;

SQLSetStmtAttr(hstmtS, SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0); // Определение типа курсора SQLSetStmtAttr(hstmtS, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_KEYSET_DRIVEN, 0); // Определение размера результирующего набора SQLSetStmtAttr(hstmtS, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) ROWS, 0); // Определение массива состояния строк SQLSetStmtAttr(hstmtS, SQL_ATTR_ROW_STATUS_PTR, (SQLPOINTER) rgfRowStatus, 0); SQLSetCursorName(hstmtS, "C1", SQL_NTS); // Выполнение SQL-оператора SQLExecDirect(hstmtS, "SELECT ID1, STATUS FROM TBL1", SQL_NTS); // Выполнение "связывания" данных SQLBindCol(hstmtS, 1, SQL_C_ULONG, &sID, 0, &cbID); SQLBindCol(hstmtS, 2, SQL_C_CHAR, szStatus, STATUS_LEN, &cbStatus);


while ((retcode == SQLFetchScroll(hstmtS, SQL_FETCH_NEXT, 0)) != SQL_ERROR) { if (retcode == SQL_NO_DATA_FOUND) break; // Отображение 20-ти извлеченных строк // результирующего набора for (irow = 0; irow < crow; irow++) { if (rgfRowStatus[irow] != SQL_ROW_DELETED) // Отображение данных printf("%2d %5d %*s\n", irow+1, sID, NAME_LEN-1, szStatus[irow]); } while (TRUE) { printf("\ nУкажите номер изменяемой строки или 0?"); gets(szReply); // Получаем номер строки irow = atoi(szReply); if (irow > 0 && irow <= crow) { printf("\nНовое состояние?"); gets(szStatus[irow-1]); // Получаем новое // значение для поля STATUS // Изменяем текущую позицию курсора SQLSetPos(hstmtS, irow, SQL_POSITION, SQL_LOCK_NO_CHANGE); SQLPrepare(hstmtU, "UPDATE TBL1 SET STATUS=? WHERE CURRENT OF C1", SQL_NTS); // Выполняем "связывание" параметра SQLBindParameter(hstmtU, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, STATUS_LEN, 0, szStatus[irow], 0, NULL); // Выполняем изменение данных SQLExecute(hstmtU); } else if (irow == 0) { break; } } }


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