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

Блочная выборка данных

< Лекция 6 || Лекция 7: 123 || Лекция 8 >

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

При использовании связывания по строкам определяется структура, содержащая от одного до трех элементов для каждого столбца извлекаемых данных. Первый элемент предназначается для извлекаемых данных, второй - для длины / индикатора буфера, третий - для индикатора буфера при раздельном сохранении значений длины и индикатора (что определяется дескрипторами полей 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);
< Лекция 6 || Лекция 7: 123 || Лекция 8 >