SQLBindCol 函式

符合性
引進版本:ODBC 1.0 標準合規性:ISO 92

總結
SQLBindCol 將應用程式資料緩衝區綁定到結果集中的欄位。

Syntax

  
SQLRETURN SQLBindCol(  
      SQLHSTMT       StatementHandle,  
      SQLUSMALLINT   ColumnNumber,  
      SQLSMALLINT    TargetType,  
      SQLPOINTER     TargetValuePtr,  
      SQLLEN         BufferLength,  
      SQLLEN *       StrLen_or_IndPtr);  

論點

StatementHandle
[輸入]語句句柄。

欄位編號
[輸入]結果集欄位的數量要綁定。 欄位編號依從 0 開始的遞增排列,第 0 欄為書籤欄位。 若未使用書籤——也就是說,SQL_ATTR_USE_BOOKMARKS 陳述句屬性設為 SQL_UB_OFF——則欄位號碼從 1 開始。

目標類型
[輸入]*TargetValuePtr 緩衝區的 C 資料型別識別碼。 當驅動程式使用 SQLFetchSQLFetchScrollSQLBulkOperationsSQLSetPos 從資料來源擷取資料時,會將資料轉換成此類型;當它用 SQLBulkOperationsSQLSetPos 將資料傳送到資料來源時,驅動程式會將資料從此類型轉換出來。 有關有效的 C 資料型態與型別識別碼清單,請參閱附錄 D:資料型別中的 C 資料型別 章節。

TargetType 參數為區間資料型態,則資料會使用預設的區間領先精度(2)與預設區間秒精度(6),分別設定在 ARD 的SQL_DESC_DATETIME_INTERVAL_PRECISION與SQL_DESC_PRECISION欄位中。 若 TargetType 參數為 SQL_C_NUMERIC,則會使用預設的精確度(驅動程式定義)與預設縮放度(0),這些參數在 ARD 的 SQL_DESC_PRECISION 與 SQL_DESC_SCALE 欄位中設定。 若預設精度或縮放不適當,應用程式應透過呼叫 SQLSetDescFieldSQLSetDescRec 明確設定相應描述符欄位。

您也可以指定擴充的 C 資料類型。 欲了解更多資訊,請參閱 ODBC 中的 C 資料型別。

目標值Ptr
[延遲輸入/輸出]將指標指向資料緩衝區,綁定到該欄位。 SQLFetchSQLFetchScroll 會在這個緩衝區回傳資料。 當操作SQL_FETCH_BY_BOOKMARK時,SQLBulkOperations 會回傳此緩衝區的資料;當操作SQL_ADD或SQL_UPDATE_BY_BOOKMARK時,它會從此緩衝區取得資料。 當操作SQL_REFRESH時,SQLSetPos 會回傳此緩衝區的資料;當操作SQL_UPDATE時,它會從此緩衝區取得資料。

TargetValuePtr 是空指標,驅動程式會解綁該欄位的資料緩衝區。 應用程式可以透過呼叫 SQLFreeStmt 並啟用 SQL_UNBIND 選項來解除所有欄位的綁定。 應用程式可以解除欄位的資料緩衝區,但仍有長度/指示符的緩衝區,若呼叫 SQLBindCol 時的 TargetValuePtr 參數是空指標,但 StrLen_or_IndPtr 參數是有效值。

BufferLength
[輸入]*TargetValuePtr 緩衝區的長度(以位元組為單位)。

驅動程式使用 BufferLength 以避免在回傳可變長度資料(如字元或二進位資料)時寫入超過*TargetValuePtr 緩衝區的末尾。 請注意,驅動程式在回傳字元資料至 *TargetValuePtr. 時會計數空終止字元。 *因此,TargetValuePtr 必須包含空終止字元的空間,否則驅動程式會截斷資料。

當驅動程式回傳固定長度的資料,例如整數或日期結構時,會忽略 緩衝區 長度,並假設緩衝區足夠大以容納資料。 因此,應用程式必須為固定長度資料分配足夠大的緩衝區,否則驅動程式會寫入緩衝區末端以外。

BufferLength 小於 0 時,SQLBindCol 會回傳 SQLSTATE HY090(字串或緩衝區長度無效),但當 BufferLength 為 0 時則不會。 然而,如果 TargetType 指定字元類型,應用程式不應將 BufferLength 設為 0,因為符合 ISO CLI 標準的驅動程式會回傳 SQLSTATE HY090(無效字串或緩衝區長度)。

StrLen_or_IndPtr
[延遲輸入/輸出]用指標指向長度/指示緩衝區綁定到欄位。 SQLFetchSQLFetchScroll 會在這個緩衝區回傳一個值。 當操作SQL_ADD、SQL_UPDATE_BY_BOOKMARK或SQL_DELETE_BY_BOOKMARK時,SQLBulkOperations 會從此緩衝區取得一個值。 當操作SQL_FETCH_BY_BOOKMARK時,SQLBulkOperations 會回傳此緩衝區的值。 當操作SQL_REFRESH時,SQLSetPos 會回傳此緩衝區的值;當 Operation SQL_UPDATE時,它會從此緩衝區取得一個值。

SQLFetchSQLFetchScrollSQLBulkOperationsSQLSetPos 可在長度/指示緩衝區回傳以下值:

  • 可回傳資料長度

  • SQL_NO_TOTAL

  • SQL_NULL_DATA

應用程式可在長度/指示緩衝區中輸入以下值,供 SQLBulkOperationsSQLSetPos 使用:

  • 傳送資料的長度

  • SQL_NTS

  • SQL_NULL_DATA

  • SQL_DATA_AT_EXEC

  • SQL_LEN_DATA_AT_EXEC巨集的結果

  • SQL_COLUMN_IGNORE

如果指示緩衝區和長度緩衝區是獨立的緩衝區,指示緩衝區只能回傳 SQL_NULL_DATA,而長度緩衝區則能回傳所有其他值。

欲了解更多資訊,請參閱 SQLBulkOperations 函式SQLFetch 函式SQLSetPos 函式,以及 使用 長度/指示值

StrLen_or_IndPtr 為空指標,則不使用長度或指示值。 這是在擷取資料時的錯誤,且資料為 NULL。

如果您的應用程式將在64位作業系統上執行,請參閱 ODBC 64位資訊

Returns

SQL_SUCCESS、SQL_SUCCESS_WITH_INFO、SQL_ERROR或SQL_INVALID_HANDLE。

Diagnostics

SQLBindCol 回傳 SQL_ERROR 或 SQL_SUCCESS_WITH_INFO 時,可以透過呼叫 SQLGetDiagRec 並設定 HandleType 為 SQL_HANDLE_STMT 和 Handle StatementHandle 來取得相關的 SQLSTATE 值。 下表列出 SQLBindCol 通常回傳的 SQLSTATE 值,並在此函式情境下說明每個值;「(DM)」符號會置於驅動程式管理器回傳的 SQLSTATE 描述前。 除非另有說明,否則與每個 SQLSTATE 值相關聯的傳回碼會SQL_ERROR。

SQLSTATE 錯誤 說明
01000 一般警告 驅動程式特定的資訊訊息。 (函式會傳回SQL_SUCCESS_WITH_INFO。)
07006 受限制的數據類型屬性違規 (DM) ColumnNumber 參數為 0,TargetType 參數也不是 SQL_C_BOOKMARK 或 SQL_C_VARBOOKMARK。
07009 無效描述子索引 參數 ColumnNumber 所指定的值超過結果集中最大欄位數。
HY000 一般誤差 發生錯誤,其中沒有特定的 SQLSTATE,也沒有定義任何實作特定的 SQLSTATE。 *MessageText 緩衝區中 SQLGetDiagRec回的錯誤訊息描述錯誤及其原因。
HY001 記憶體配置錯誤 驅動程式無法配置支援執行或完成函式所需的記憶體。
HY003 無效的應用程式緩衝區類型 TargetType 這個參數既不是有效的資料型別,也不是SQL_C_DEFAULT。
HY010 函式順序錯誤 (DM) 已針對與 StatementHandle 相關聯的連接句柄呼叫異步執行函式。 當呼叫 SQLBindCol 時,這個非同步函式仍在執行中。

(DM) 已針對 StatementHandle 呼叫 SQLExecuteSQLExecDirectSQLMoreResults,並傳回SQL_PARAM_DATA_AVAILABLE。 在擷取所有數據流參數的數據之前,會呼叫此函式。

(DM) 呼叫 StatementHandle 的異步執行函式,並在呼叫此函式時仍在執行。

(DM) 已針對 StatementHandle 呼叫 SQLExecuteSQLExecDirectSQLBulkOperationsSQLSetPos,並傳回SQL_NEED_DATA。 在針對所有數據執行中參數或數據行傳送數據之前,會呼叫此函式。
HY013 記憶體管理錯誤 無法處理函式呼叫,因為基礎記憶體物件無法存取,可能是因為記憶體不足的情況。
HY090 無效的字串或緩衝區長度 (DM) 參數 BufferLength 指定的值小於 0。

(DM)駕駛員是ODBC 2型。x 驅動程式中, ColumnNumber 參數設為 0,且參數 BufferLength 指定的值不等於 4。
HY117 聯機因為未知的交易狀態而暫停。 只允許中斷連線和唯讀函式。 (DM) 如需暫停狀態的詳細資訊,請參閱 SQLEndTran 函式
HYC00 未實作選擇性功能 驅動程式或資料來源不支援 TargetType 參數與相應欄位驅動程式專用 SQL 資料型態組合所指定的轉換。

參數 ColumnNumber 為 0,且驅動程式不支援書籤。

驅動程式僅支援 ODBC 2。x 以及 TargetType 參數為以下之一:

SQL_C_NUMERIC SQL_C_SBIGINT SQL_C_UBIGINT

以及附錄D:資料型別中C型別中列出的任何區間C資料型別。

驅動程式僅支援 3.50 之前的 ODBC 版本,且參數 TargetType 被SQL_C_GUID。
HYT01 連線已逾時 在數據源回應要求之前,連線逾時期限已過期。 線上逾時期間是透過 SQLSetConnectAttr 來設定,SQL_ATTR_CONNECTION_TIMEOUT。
IM001 驅動程式不支援此函式 (DM) 與 StatementHandle 相關聯的驅動程式不支援 函式。

評論

SQLBindCol 用於將結果集中的欄位與應用程式中的資料緩衝區及長度/指示符緩衝區關聯或 綁定 。 當應用程式呼叫 SQLFetchSQLFetchScrollSQLSetPos 來擷取資料時,驅動程式會回傳指定緩衝區中綁定欄位的資料;欲了解更多資訊,請參閱 SQLFetch 函式。 當應用程式呼叫 SQLBulkOperations 來更新或插入資料列,或呼叫 SQLSetPos 來更新資料時,驅動程式會從指定的緩衝區取得綁定欄位的資料;欲了解更多資訊,請參閱 SQLBulkOperations 函式SQLSetPos 函式。 欲了解更多綁定資訊,請參閱「 檢索結果(基本)」。

請注意,欄位不必綁定即可取得資料。 應用程式也可以呼叫 SQLGetData 從欄位擷取資料。 雖然可以綁定某一列中的某些欄位並呼叫 其他 欄位,但這會受到一些限制。 欲了解更多資訊,請參閱 SQLGetData

裝訂、解裝與重新裝訂欄位

欄位可以隨時被綁定、解綁或重新綁定,即使資料已從結果集取得。 新綁定會在下一次呼叫使用綁定的函式時生效。 例如,假設一個應用程式綁定結果集中的欄位並呼叫 SQLFetch。 驅動程式會回傳綁定緩衝區的資料。 現在假設應用程式將欄位綁定到另一組緩衝區。 驅動程式不會將剛取出的資料放入新綁定的緩衝區。 相反地,它會等到 SQLFetch 再次被呼叫時,再將下一列的資料放入新綁定的緩衝區。

Note

在將欄位綁定到欄位 0 前,應該先設定 statement 屬性SQL_ATTR_USE_BOOKMARKS。 這不是必須的,但強烈建議。

綁定欄位

要綁定欄位,應用程式呼叫 SQLBindCol ,並傳遞資料緩衝區的欄位號、類型、位址與長度,以及長度/指示緩衝區的位址。 關於這些位址的使用方式,請參閱本節後面的「緩衝區位址」。 欲了解更多關於綁定欄位的資訊,請參閱 使用 SQLBindCol

這些緩衝區的使用會被延遲;也就是說,應用程式以 SQLBindCol 綁定這些函式,但驅動程式則從其他函式存取,例如 SQLBulkOperationsSQLFetchSQLFetchScrollSQLSetPos。 應用程式有責任確保 SQLBindCol 中指定的指標只要綁定有效,就能保持有效。 如果應用程式允許這些指標失效——例如釋放緩衝區——然後呼叫一個預期它們有效的函式,後果則未定義。 更多資訊請參閱 延緩緩衝區

該綁定會持續有效,直到被新的綁定取代、欄位解除綁定,或陳述被釋放為止。

解綁柱

要解綁單一欄位,應用程式呼叫 SQLBindCol ,並將 ColumnNumber 設為該欄位的編號, TargetValuePtr 設定為空指標。 若 ColumnNumber 指的是未綁定的欄位, SQLBindCol 仍會回傳 SQL_SUCCESS。

要解綁所有欄位,應用程式呼叫 SQLFreeStmt ,並將 fOption 設為 SQL_UNBIND。 這也可以透過將ARD的SQL_DESC_COUNT場設為零來達成。

重新裝訂柱

應用程式可以執行兩個作業之一來變更系結:

  • 呼叫 SQLBindCol 來指定一個已經綁定的欄位的新綁定。 驅動程式會以新的系結覆寫舊的系結。

  • 指定一個由綁定呼叫 SQLBindCol 指定的緩衝區位址要加入的偏移量。 欲了解更多資訊,請參閱下一節「綁定偏移」。

綁定偏移量

綁定偏移量是在資料與長度/指示緩衝區的位址(如 TargetValuePtrStrLen_or_IndPtr 參數中指定)被加入的值,然後再被取消引用。 當使用偏移量時,綁定會成為應用程式緩衝區佈局的「範本」,應用程式可以透過改變偏移量將此「範本」移至記憶體的不同區域。 由於每個綁定中每個位址都加入相同的偏移量,因此不同欄位的緩衝區間相對偏移量必須在每組緩衝區內相同。 當採用逐行綁定時,這點總是成立;應用程式必須仔細規劃緩衝區,才能在使用逐欄綁定時達到此標準。

使用綁定偏移量的效果基本上和呼叫 SQLBindCol 重新綁定欄位差不多。 差別在於,呼叫 SQLBindCol 會指定資料緩衝區及長度/指示緩衝區的新位址,而使用綁定偏移量不會改變位址,只是增加偏移量。 應用程式可以隨時指定新的偏移量,且這個偏移量總是會加入原本綁定的位址。 特別是,若偏移量設為 0,或語句屬性設為空指標,驅動程式則使用原本綁定的位址。

為了指定綁定偏移量,應用程式會將 SQL_ATTR_ROW_BIND_OFFSET_PTR 陳述句屬性設為 SQLINTEGER 緩衝區的位址。 在應用程式呼叫使用綁定的函式之前,會在此緩衝區中放入位元組的偏移量。 為了確定緩衝區的位址,驅動程式會將偏移量加到綁定中的位址上。 位址與偏移量的總和必須是有效的位址,但偏移量加入的位址不必是有效的。 欲了解更多綁定偏移量的使用資訊,請參閱本節後面的「緩衝區位址」。

綁定陣列

若列集大小(SQL_ATTR_ROW_ARRAY_SIZE 陳述式屬性的值)大於 1,應用程式會綁定緩衝區陣列而非單一緩衝區。 欲了解更多資訊,請參閱 「阻擋游標」。

應用程式可以用兩種方式綁定陣列:

  • 將陣列綁定到每一欄。 這稱為 逐欄綁定 ,因為每個資料結構(陣列)都包含單一欄位的資料。

  • 定義一個結構來儲存整列的資料,並綁定這些結構的陣列。 這稱為 列式綁定 ,因為每個資料結構都包含單一列的資料。

每個緩衝區陣列的元素數量必須至少等於行集大小。

Note

應用程式必須驗證對齊是否有效。 欲了解更多關於對齊考量的資訊,請參閱 對齊

Column-Wise 系結

在逐欄綁定中,應用程式會將獨立的資料陣列及長度/指示器陣列綁定到每一欄。

若要使用逐欄綁定,應用程式首先將 SQL_ATTR_ROW_BIND_TYPE 陳述式屬性設為 SQL_BIND_BY_COLUMN。 (這是預設值。針對要繫結的每個資料行,應用程式會執行下列步驟:

  1. 分配一個資料緩衝陣列。

  2. 配置長度/指標緩衝區的陣列。

    Note

    如果使用數據行型系結時,應用程式會直接寫入描述項,則可以將個別數位件用於長度和指標數據。

  3. 呼叫 SQLBindCol 並使用以下參數:

    • TargetType 是資料緩衝區陣列中單一元素的類型。

    • TargetValuePtr 是資料緩衝陣列的位址。

    • BufferLength 是資料緩衝陣列中單一元素的大小。 當數據是固定長度的數據時,會忽略 BufferLength 自變數。

    • StrLen_or_IndPtr是長度/指標陣列的位址。

關於這些資訊如何使用,請參見本節後面的「緩衝區位址」。 欲了解更多關於逐欄裝訂的資訊,請參見 Column-Wise 裝訂

Row-Wise 系結

在列式綁定中,應用程式定義一個結構,包含每個待綁定欄位的資料緩衝區及長度/指示符緩衝區。

若要使用資料列系結,應用程式會執行下列步驟:

  1. 定義一個結構以儲存單一資料列(包括資料及長度/指示緩衝區),並分配這些結構的陣列。

    Note

    如果使用數據列系結時,應用程式會直接寫入描述項,則可以將個別欄位用於長度和指標數據。

  2. 將 SQL_ATTR_ROW_BIND_TYPE 陳述句屬性設定為包含單一資料列的結構大小,或是將結果欄位綁定的緩衝區實例大小。 長度必須包含所有綁定欄位的空間,以及結構或緩衝區的任何填充,以確保當綁定欄位的位址以指定長度遞增時,結果會指向下一列同一欄位的起始。 在 ANSI C 中使用 sizeof 運算符時,會保證此行為。

  3. 呼叫 SQLBindCol ,並對每個要綁定的欄位設定以下參數:

    • TargetType 是要綁定到該欄位的資料緩衝區成員類型。

    • TargetValuePtr 是第一個陣列元素中資料緩衝區成員的位址。

    • BufferLength 是資料緩衝區成員的大小。

    • StrLen_or_IndPtr是要系結之長度/指標成員的位址。

關於這些資訊如何使用,請參見本節後面的「緩衝區位址」。 欲了解更多關於逐欄裝訂的資訊,請參見 Row-Wise 裝訂

緩衝區位址

緩衝區位址是資料或長度/指示緩衝區的實際位址。 驅動程式會在寫入緩衝區前(例如擷取時間)計算緩衝區位址。 它是根據以下公式計算,該公式使用了 TargetValuePtrStrLen_or_IndPtr 參數中指定的位址、綁定偏移量,以及列號:

綁定位址 + 綁定偏移 量 + ((列號 - 1) x 元素大小

其中公式的變數定義如下表所述。

Variable 說明
綁定位址 對於資料緩衝區,則使用 SQLBindColTargetValuePtr 參數指定的位址。

對於長度/指示緩衝區,則使用SQLBindColStrLen_or_IndPtr參數指定的位址。 欲了解更多資訊,請參閱「描述符與 SQLBindCol」章節中的「附加註解」。

若綁定位址為 0,則不會回傳資料值,即使前述公式計算的位址非零。
綁定偏移量 若使用列綁定,則以 SQL_ATTR_ROW_BIND_OFFSET_PTR 陳述屬性指定的位址儲存值。

若使用逐欄綁定,或 SQL_ATTR_ROW_BIND_OFFSET_PTR 陳述句屬性的值為空指標,則 綁定偏移 量為 0。
排號 行集中該列的以 1 為基礎的數字。 對於預設的單列取指,這是 1。
元素大小 綁定陣列中元素的大小。

若使用欄式綁定,長度/指示緩衝區的 大小(SQLINTEGER) 為單位。 對於資料緩衝區,若資料型態為可變長度,則為 SQLBindColBufferLength 參數的值;若資料型別為固定長度,則為資料型態的大小。

若使用列式綁定,則為資料與長度/指示緩衝區的 SQL_ATTR_ROW_BIND_TYPE 陳述式屬性值。

描述符與 SQLBindCol

以下章節說明 SQLBindCol 如何與描述符互動。

Caution

呼叫一個語句的 SQLBindCol 可能會影響其他語句。 當明確配置與語句相關聯的 ARD,也與其他語句相關聯時,就會發生這種情況。 由於 SQLBindCol 會修改描述符,因此修改適用於所有與此描述符相關聯的語句。 若此行為不符合要求,應用程式應在呼叫 SQLBindCol 前將此描述符與其他語句分離。

參數映射

概念上, SQLBindCol 依序執行以下步驟:

  1. 呼叫 SQLGetStmtAttr 以取得 ARD 帳號。

  2. 呼叫 SQLGetDescField 取得該描述符的SQL_DESC_COUNT欄位,若 ColumnNumber 參數中的值超過 SQL_DESC_COUNT,則呼叫 SQLSetDescField 將 SQL_DESC_COUNT 的值提高至 ColumnNumber

  3. 多次呼叫 SQLSetDescField ,將值指派給 ARD 的以下欄位:

    • 將 SQL_DESC_TYPE 和 SQL_DESC_CONCISE_TYPE 設定為 TargetType 的值,但若 TargetType 是日期時間或區間子類型的簡潔識別碼之一,則分別將 SQL_DESC_TYPE 設定為 SQL_DATETIME 或 SQL_INTERVAL;將SQL_DESC_CONCISE_TYPE設為簡潔識別碼;並將SQL_DESC_DATETIME_INTERVAL_CODE設為對應的日期時間或區間子碼。

    • 根據 TargetType 的適用,設定一個或多個 SQL_DESC_LENGTH、SQL_DESC_PRECISION、SQL_DESC_SCALE 和 SQL_DESC_DATETIME_INTERVAL_PRECISION。

    • 將 [SQL_DESC_OCTET_LENGTH] 字段設定為 BufferLength 的值

    • 將SQL_DESC_DATA_PTR欄位設為 TargetValuePtr

    • 將SQL_DESC_INDICATOR_PTR欄位設為 StrLen_or_IndPtr。 (詳見下一段。)

    • 將SQL_DESC_OCTET_LENGTH_PTR欄位設為 StrLen_or_IndPtr。 (詳見下一段。)

StrLen_or_IndPtr參數所指的變數同時用於指示和長度資訊。 如果擷取遇到欄位的空值,會將SQL_NULL_DATA存在這個變數中;否則,資料長度會儲存在這個變數中。 將空指標作為 StrLen_or_IndPtr 傳遞會阻止擷取操作回傳資料長度,但若遇到空值且無法回傳 SQL_NULL_DATA,擷取會失敗。

若呼叫 SQLBindCol 失敗,ARD 中應設定的描述符欄位內容未定義,且 ARD SQL_DESC_COUNT 欄位的值不變。

COUNT 欄位的隱式重置

SQLBindCol 只有在 ColumnNumber 參數會增加 SQL_DESC_COUNT 值時,才會將 SQL_DESC_COUNT 設定為 ColumnNumber 參數的值。 若 TargetValuePtr 參數中的值為空指標,且 ColumnNumber 參數中的值等於 SQL_DESC_COUNT(即解綁最高束縛欄時),則 SQL_DESC_COUNT 設為剩餘最高束縛欄的編號。

關於SQL_DEFAULT的注意事項

為了成功取得欄位資料,應用程式必須正確判定應用程式緩衝區中資料的長度與起始點。 當應用程式明確指定 TargetType 時,應用程式誤解很容易被發現。 然而,當應用程式指定 SQL_DEFAULT 的 TargetType (目標類型)時, SQLBindCol 可以套用到與應用程式預期資料不同的欄位,無論是透過變更元資料或將程式碼套用到不同欄位。 在這種情況下,應用程式可能不一定能確定擷取欄位資料的起始或長度。 這可能導致未報告的資料錯誤或記憶體違規。

程式碼範例

在以下範例中,應用程式會在 Customers 資料表執行 SELECT 語句,回傳一組依姓名排序的客戶 ID、姓名與電話號碼的結果集。 接著呼叫 SQLBindCol 將資料欄位綁定到本地緩衝區。 最後,應用程式會用 SQLFetch 擷取每一列資料,並列印每位客戶的姓名、ID 和電話號碼。

更多程式碼範例請參見 SQLBulkOperations FunctionSQLColumns FunctionSQLFetchScroll FunctionSQLSetPos Function

// SQLBindCol_ref.cpp  
// compile with: odbc32.lib  
#include <windows.h>  
#include <stdio.h>  
  
#define UNICODE  
#include <sqlext.h>  
  
#define NAME_LEN 50  
#define PHONE_LEN 60
  
void show_error() {  
   printf("error\n");  
}  
  
int main() {  
   SQLHENV henv;  
   SQLHDBC hdbc;  
   SQLHSTMT hstmt = 0;  
   SQLRETURN retcode;  
   SQLWCHAR szName[NAME_LEN], szPhone[PHONE_LEN], sCustID[NAME_LEN];  
   SQLLEN cbName = 0, cbCustID = 0, cbPhone = 0;  
  
   // Allocate environment handle  
   retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);  
  
   // Set the ODBC version environment attribute  
   if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
      retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);   
  
      // Allocate connection handle  
      if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
         retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);  
  
         // Set login timeout to 5 seconds  
         if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
            SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);  
  
            // Connect to data source  
            retcode = SQLConnect(hdbc, (SQLWCHAR*) L"NorthWind", SQL_NTS, (SQLWCHAR*) NULL, 0, NULL, 0);  
  
            // Allocate statement handle  
            if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {   
               retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);   
  
               retcode = SQLExecDirect(hstmt, (SQLWCHAR *) L"SELECT CustomerID, ContactName, Phone FROM CUSTOMERS ORDER BY 2, 1, 3", SQL_NTS);  
               if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
  
                  // Bind columns 1, 2, and 3  
                  retcode = SQLBindCol(hstmt, 1, SQL_C_WCHAR, &sCustID, 100, &cbCustID);  
                  retcode = SQLBindCol(hstmt, 2, SQL_C_WCHAR, szName, NAME_LEN, &cbName);  
                  retcode = SQLBindCol(hstmt, 3, SQL_C_WCHAR, szPhone, PHONE_LEN, &cbPhone);   
  
                  // Fetch and print each row of data. On an error, display a message and exit.  
                  for (int i=0 ; ; i++) {  
                     retcode = SQLFetch(hstmt);  
                     if (retcode == SQL_ERROR || retcode == SQL_SUCCESS_WITH_INFO)  
                        show_error();  
                     if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)  
                     {
                        //replace wprintf with printf
                        //%S with %ls
                        //warning C4477: 'wprintf' : format string '%S' requires an argument of type 'char *'
                        //but variadic argument 2 has type 'SQLWCHAR *'
                        //wprintf(L"%d: %S %S %S\n", i + 1, sCustID, szName, szPhone);  
                        printf("%d: %ls %ls %ls\n", i + 1, sCustID, szName, szPhone);  
                    }    
                     else  
                        break;  
                  }  
               }  
  
               // Process data  
               if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
                  SQLCancel(hstmt);  
                  SQLFreeHandle(SQL_HANDLE_STMT, hstmt);  
               }  
  
               SQLDisconnect(hdbc);  
            }  
  
            SQLFreeHandle(SQL_HANDLE_DBC, hdbc);  
         }  
      }  
      SQLFreeHandle(SQL_HANDLE_ENV, henv);  
   }  
}  

另請參閱 ODBC 範例課程

如需相關信息 看!
傳回結果集中數據行的相關信息 SQLDescribeCol 函式
擷取數據區塊或捲動結果集 SQLFetchScroll 函式
擷取多個數據列 SQLFetch 函式
釋放陳述句上的欄緩衝區 SQLFreeStmt 函式
擷取部分或所有數據行的數據 SQLGetData 函式
回傳結果集欄位數 SQLNumResultCols 函數