按列绑定
使用按列绑定时,应用程序会为将返回数据的每一列绑定一个或两个数组,某些情况下会绑定三个数组。 第一个数组保存数据值,第二个数组保存长度/标记缓冲区。 标记和长度值可以通过将 SQL_DESC_INDICATOR_PTR 和 SQL_DESC_OCTET_LENGTH_PTR 描述符字段设置为不同的值来存储在单独的缓冲区中;如果执行了此操作,会绑定第三个数组。 每个数组包含的元素数与行集中的行数一样多。
应用程序声明它正在使用具有 SQL_ATTR_ROW_BIND_TYPE 语句属性的按列绑定,这可确定行集缓冲区的绑定类型,而不是参数集缓冲区。 驱动程序会返回每个数组连续元素中每行的数据。 下图显示了按列绑定的工作原理。
例如,以下代码将 10 个元素数组绑定到 OrderID、SalesPerson 和 Status 列:
#define ROW_ARRAY_SIZE 10
SQLUINTEGER OrderIDArray[ROW_ARRAY_SIZE], NumRowsFetched;
SQLCHAR SalesPersonArray[ROW_ARRAY_SIZE][11],
StatusArray[ROW_ARRAY_SIZE][7];
SQLINTEGER OrderIDIndArray[ROW_ARRAY_SIZE],
SalesPersonLenOrIndArray[ROW_ARRAY_SIZE],
StatusLenOrIndArray[ROW_ARRAY_SIZE];
SQLUSMALLINT RowStatusArray[ROW_ARRAY_SIZE], i;
SQLRETURN rc;
SQLHSTMT hstmt;
// Set the SQL_ATTR_ROW_BIND_TYPE statement attribute to use
// column-wise binding. 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 cRowsFetched.
SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_BIND_TYPE, SQL_BIND_BY_COLUMN, 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 arrays to the OrderID, SalesPerson, and Status columns.
SQLBindCol(hstmt, 1, SQL_C_ULONG, OrderIDArray, 0, OrderIDIndArray);
SQLBindCol(hstmt, 2, SQL_C_CHAR, SalesPersonArray, sizeof(SalesPersonArray[0]),
SalesPersonLenOrIndArray);
SQLBindCol(hstmt, 3, SQL_C_CHAR, StatusArray, sizeof(StatusArray[0]),
StatusLenOrIndArray);
// 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_ERROR not 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 (OrderIDIndArray[i] == SQL_NULL_DATA)
printf(" NULL ");
else
printf("%d\t", OrderIDArray[i]);
if (SalesPersonLenOrIndArray[i] == SQL_NULL_DATA)
printf(" NULL ");
else
printf("%s\t", SalesPersonArray[i]);
if (StatusLenOrIndArray[i] == SQL_NULL_DATA)
printf(" NULL\n");
else
printf("%s\n", StatusArray[i]);
}
}
}
// Close the cursor.
SQLCloseCursor(hstmt);