Sdílet prostřednictvím


Row-Wise Vazba

Při použití vazby s řádky definuje aplikace strukturu obsahující jednu nebo dvě, nebo v některých případech tři prvky pro každý sloupec, pro který se mají data vrátit. První prvek obsahuje datovou hodnotu a druhý prvek obsahuje vyrovnávací paměť délky/indikátoru. Ukazatele a hodnoty délky mohou být uloženy v samostatných vyrovnávacích pamětích nastavením polí SQL_DESC_INDICATOR_PTR a SQL_DESC_OCTET_LENGTH_PTR popisovačů na různé hodnoty. Pokud se to provede, struktura obsahuje třetí prvek. Aplikace pak přidělí pole těchto struktur, které obsahuje tolik prvků, kolik je řádků v sadě řádků.

Aplikace deklaruje velikost struktury pro ovladač s atributem příkazu SQL_ATTR_ROW_BIND_TYPE a váže adresu každého člena v prvním prvku pole. Ovladač tedy může vypočítat adresu dat pro určitý řádek a sloupec jako

Address = Bound Address + ((Row Number - 1) * Structure Size)  

kde jsou řádky očíslovány od 1 do velikosti sady řádků. (Jedna se odečte od čísla řádku, protože indexování pole v jazyce C je založené na nule.) Následující obrázek znázorňuje, jak funguje vazby podle řádků. Obecně platí, že do struktury jsou zahrnuty pouze sloupce, které budou svázány. Struktura může obsahovat pole, která nesouvisejí se sloupci sady výsledků. Sloupce lze umístit do struktury v libovolném pořadí, ale jsou zobrazeny v sekvenčním pořadí pro přehlednost.

Zobrazuje vazbu podle řádků.

Například následující kód vytvoří strukturu s prvky, ve kterých se mají vracet data pro sloupce OrderID, SalesPerson a Status a délka/indikátory pro sloupce SalesPerson a Status. Přidělí 10 těchto struktur a vytvoří vazbu na sloupce OrderID, SalesPerson a Status.

#define ROW_ARRAY_SIZE 10  
  
// Define the ORDERINFO struct and allocate an array of 10 structs.  
typedef struct {  
   SQLUINTEGER   OrderID;  
   SQLINTEGER    OrderIDInd;  
   SQLCHAR       SalesPerson[11];  
   SQLINTEGER    SalesPersonLenOrInd;  
   SQLCHAR       Status[7];  
   SQLINTEGER    StatusLenOrInd;  
} ORDERINFO;  
ORDERINFO OrderInfoArray[ROW_ARRAY_SIZE];  
  
SQLULEN    NumRowsFetched;  
SQLUSMALLINT   RowStatusArray[ROW_ARRAY_SIZE], i;  
SQLRETURN      rc;  
SQLHSTMT       hstmt;  
  
// Specify the size of the structure with the SQL_ATTR_ROW_BIND_TYPE  
// statement attribute. This also declares that row-wise binding will  
// be used. Declare the rowset size with the SQL_ATTR_ROW_ARRAY_SIZE  
// statement attribute. Set the SQL_ATTR_ROW_STATUS_PTR statement  
// attribute to point to the row status array. Set the  
// SQL_ATTR_ROWS_FETCHED_PTR statement attribute to point to  
// NumRowsFetched.  
SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_BIND_TYPE, sizeof(ORDERINFO), 0);  
SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, ROW_ARRAY_SIZE, 0);  
SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_STATUS_PTR, RowStatusArray, 0);  
SQLSetStmtAttr(hstmt, SQL_ATTR_ROWS_FETCHED_PTR, &NumRowsFetched, 0);  
  
// Bind elements of the first structure in the array to the OrderID,  
// SalesPerson, and Status columns.  
SQLBindCol(hstmt, 1, SQL_C_ULONG, &OrderInfoArray[0].OrderID, 0, &OrderInfoArray[0].OrderIDInd);  
SQLBindCol(hstmt, 2, SQL_C_CHAR, OrderInfoArray[0].SalesPerson,  
            sizeof(OrderInfoArray[0].SalesPerson),  
            &OrderInfoArray[0].SalesPersonLenOrInd);  
SQLBindCol(hstmt, 3, SQL_C_CHAR, OrderInfoArray[0].Status,  
            sizeof(OrderInfoArray[0].Status), &OrderInfoArray[0].StatusLenOrInd);  
  
// Execute a statement to retrieve rows from the Orders table.  
SQLExecDirect(hstmt, "SELECT OrderID, SalesPerson, Status FROM Orders", SQL_NTS);  
  
// Fetch up to the rowset size number of rows at a time. Print the actual  
// number of rows fetched; this number is returned in NumRowsFetched.  
// Check the row status array to print only those rows successfully  
// fetched. Code to check if rc equals SQL_SUCCESS_WITH_INFO or  
// SQL_ERRORnot shown.  
while ((rc = SQLFetchScroll(hstmt,SQL_FETCH_NEXT,0)) != SQL_NO_DATA) {  
   for (i = 0; i < NumRowsFetched; i++) {  
      if (RowStatusArray[i] == SQL_ROW_SUCCESS|| RowStatusArray[i] ==   
         SQL_ROW_SUCCESS_WITH_INFO) {  
         if (OrderInfoArray[i].OrderIDInd == SQL_NULL_DATA)  
            printf(" NULL      ");  
         else  
            printf("%d\t", OrderInfoArray[i].OrderID);  
         if (OrderInfoArray[i].SalesPersonLenOrInd == SQL_NULL_DATA)  
            printf(" NULL      ");  
         else  
            printf("%s\t", OrderInfoArray[i].SalesPerson);  
         if (OrderInfoArray[i].StatusLenOrInd == SQL_NULL_DATA)  
            printf(" NULL\n");  
         else  
            printf("%s\n", OrderInfoArray[i].Status);  
      }  
   }  
}  
  
// Close the cursor.  
SQLCloseCursor(hstmt);