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

       

Связывание по строкам


При использовании связывания по строкам определяется структура, содержащая от одного до трех элементов для каждого столбца извлекаемых данных. Первый элемент предназначается для извлекаемых данных, второй - для длины / индикатора буфера, третий - для индикатора буфера при раздельном сохранении значений длины и индикатора (что определяется дескрипторами полей SQL_DESC_INDICATOR_PTR и SQL_DESC_OCTET_LENGTH_PTR).

Массив таких структур должен содержать количество элементов, равное числу строк в извлекаемом наборе строк.

Размер структуры (число строк) указывается атрибутом оператора SQL_ATTR_ROW_BIND_TYPE. При связывании используются адреса каждого члена первого элемента массива. Так, адрес конкретного значения из набора строк может быть вычислен следующим образом (нумерация строк с 1):

Адрес = Адрес_связывания + ((Номер_строки - 1) * Размер_структуры)

На следующем рисунке приведена схема связывания по строкам.


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

#define ROW_ARRAY_SIZE 10

// Определяем структуру TBL_INFO и создаем массив // структур, содержащий 10 элементов typedef struct { SQLUINTEGER ID1; // Для значения 1 столбца SQLINTEGER ID1Ind; // Для длины/индикатора SQLCHAR Sal[11]; // Для значения 2 столбца SQLINTEGER SalLenOrInd; SQLCHAR Status[7]; // Для значения 3 столбца SQLINTEGER StatusLenOrInd; } ORDERINFO; TBL_INFO TBL_Array[ROW_ARRAY_SIZE]; // Массив структур

SQLUINTEGER NumRowsFetched; SQLUSMALLINT RowStatusArray[ROW_ARRAY_SIZE], i; SQLRETURN rc; SQLHSTMT hstmt;

// Определяем размер структуры, используя атрибут //оператора SQL_ATTR_ROW_BIND_TYPE, и одновременно // устанавливаем тип связывания по строкам SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_BIND_TYPE, sizeof(TBL_INFO), 0);

// Используя атрибут оператора SQL_ATTR_ROW_ARRAY_SIZE // устанавливаем количество строк в извлекаемом наборе // строк SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, ROW_ARRAY_SIZE, 0);

// Используя атрибут оператора SQL_ATTR_ROW_STATUS_PTR // определяем массив состояния строк SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_STATUS_PTR, RowStatusArray, 0); // Устанавливаем атрибут оператора // SQL_ATTR_ROWS_FETCHED_PTR для указания на // NumRowsFetched SQLSetStmtAttr(hstmt, SQL_ATTR_ROWS_FETCHED_PTR, &NumRowsFetched, 0);


// Связываем поля структуры первого элемента массива // со столбцами ID1, Sal и Status SQLBindCol(hstmt, 1, SQL_C_ULONG, &TBL_Array[0].ID1, 0, &TBL_Array[0].ID1Ind); SQLBindCol(hstmt, 2, SQL_C_CHAR, TBL_Array[0].Sal, sizeof(TBL_Array[0].Sal), &TBL_Array[0].SalLenOrInd); SQLBindCol(hstmt, 3, SQL_C_CHAR, TBL_Array[0].Status, sizeof(TBL_Array[0].Status), &TBL_Array[0].StatusLenOrInd);

// Выполняем SQL-оператор SELECT для формирования // результирующего набора SQLExecDirect(hstmt, "SELECT ID1, Sal, Status FROM TBL1", SQL_NTS);

// Используя блочный курсор, извлекаем установленное //число строк while ((rc = SQLFetchScroll(hstmt,SQL_FETCH_NEXT,0)) != SQL_NO_DATA) { // Переменная NumRowsFetched содержит число // в действительности извлеченных строк for (i = 0; i < NumRowsFetched; i++) { if (RowStatusArray[i] == SQL_ROW_SUCCESS|| RowStatusArray[i] == SQL_ROW_SUCCESS_WITH_INFO) { if (TBL_Array[i].ID1Ind == SQL_NULL_DATA) std::cout<<" NULL "; else std::cout<< TBL_Array[i].ID1; if (TBL_Array[i].SalLenOrInd == SQL_NULL_DATA) std::cout<< " NULL "; else std::cout<< TBL_Array[i].Sal; if (TBL_Array[i].StatusLenOrInd == SQL_NULL_DATA) std::cout<< " NULL\n"; else std::cout<< TBL_Array[i].Status; } } } // Закрываем курсор SQLCloseCursor(hstmt);


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