Dela via


Row-Wise Bindning

När du använder radvis bindning definierar ett program en struktur som innehåller ett eller två, eller i vissa fall tre, element för varje kolumn som data ska returneras för. Det första elementet innehåller datavärdet och det andra elementet innehåller bufferten längd/indikator. Indikatorer och längdvärden kan lagras i separata buffertar genom att ange SQL_DESC_INDICATOR_PTR- och SQL_DESC_OCTET_LENGTH_PTR beskrivande fält till olika värden. Om detta görs innehåller strukturen ett tredje element. Programmet allokerar sedan en matris med dessa strukturer, som innehåller så många element som det finns rader i raduppsättningen.

Programmet deklarerar strukturens storlek till drivrutinen med SQL_ATTR_ROW_BIND_TYPE-instruktionsattributet och binder adressen till varje medlem i det första elementet i matrisen. Drivrutinen kan därför beräkna dataadressen för en viss rad och kolumn som

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

där raderna är numrerade från 1 till storleken på raduppsättningen. (En subtraheras från radnumret eftersom matrisindexering i C är nollbaserad.) Följande bild visar hur radvis bindning fungerar. I allmänhet ingår endast kolumner som ska bindas i strukturen. Strukturen kan innehålla fält som inte är relaterade till resultatuppsättningskolumner. Kolumnerna kan placeras i strukturen i valfri ordning men visas i sekventiell ordning för tydlighetens skull.

Visar radvis bindning

Följande kod skapar till exempel en struktur med element där du kan returnera data för kolumnerna OrderID, SalesPerson och Status samt längd/indikatorer för kolumnerna SalesPerson och Status. Den allokerar 10 av dessa strukturer och binder dem till kolumnerna OrderID, SalesPerson och 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);