分享方式:


SQLBindCol 函式

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

摘要
SQLBindCol 會將應用程式資料緩衝區系結至結果集中的資料行。

語法

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

引數

StatementHandle
[輸入]語句控制碼。

ColumnNumber
[輸入]要系結的結果集資料行數目。 從 0 開始,資料行會以遞增資料行順序編號,其中資料行 0 是書簽資料行。 如果未使用書簽 ,也就是說,SQL_ATTR_USE_BOOKMARKS語句屬性會設定為 SQL_UB_OFF ,則資料行編號會從 1 開始。

TargetType
[輸入]* TargetValuePtr 緩衝區之 C 資料類型的識別碼。 使用 SQLFetch、SQLFetchScroll SQLBulkOperations 或 SQLSetPos 從資料來源 擷取資料時,驅動程式會將資料轉換成此類型;當驅動程式使用 SQLBulkOperations SQLSetPos 將資料傳送至資料來源時,驅動程式會從此類型轉換資料。 如需有效 C 資料類型和類型識別碼的清單,請參閱 附錄 D: 資料類型中的 C 資料類型 一節。

如果 TargetType 引數是間隔資料類型,則會分別針對資料使用SQL_DESC_DATETIME_INTERVAL_PRECISION和SQL_DESC_PRECISION欄位所設定的預設間隔前置精確度 (2) 和預設間隔秒有效位數 (6)。 如果 TargetType 引數是SQL_C_NUMERIC,則會針對資料使用SQL_DESC_PRECISION和SQL_DESC_SCALE欄位所設定的預設有效位數(驅動程式定義)和預設小數位數 (0)。 如果有任何預設有效位數或小數位數不合適,應用程式應該藉由呼叫 SQLSetDescField SQLSetDescRec 明確設定適當的描述元欄位。

您也可以指定擴充的 C 資料類型。 如需詳細資訊,請參閱 ODBC 的 C 資料類型

TargetValuePtr
[延後輸入/輸出]要系結至資料行的資料緩衝區指標。 SQLFetch SQLFetchScroll 會傳回此緩衝區中的資料。 當 Operation SQL_FETCH_BY_BOOKMARK 時,SQLBulkOperations 會傳回此緩衝區中的資料;當 Operation SQL_ADD 或 SQL_UPDATE_BY_BOOKMARK 時 ,它會從這個緩衝區擷取資料。 當 Operation SQL_REFRESH 時,SQLSetPos 會傳回這個緩衝區中的資料;當 Operation SQL_UPDATE 時 ,它會從這個緩衝區擷取資料。

如果 TargetValuePtr 是 Null 指標,驅動程式會將資料行的資料緩衝區解除系結。 應用程式可以使用 SQL_UNBIND 選項呼叫 SQLFreeStmt 來解除所有資料行的系結。 如果 呼叫 SQLBindCol 中的 TargetValuePtr 引數是 null 指標 ,但StrLen_or_IndPtr 引數為有效值,應用程式可以解除資料行的資料緩衝區系結,但仍有長度/指標緩衝區系結。

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

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

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

當 BufferLength 小於 0,但當 BufferLength 為 0 時 SQLBindCol 會傳回 SQLSTATE HY090 (不正確字串或緩衝區長度)。 不過,如果 TargetType 指定字元類型,應用程式就不應該將 BufferLength 設定 為 0,因為符合 ISO CLI 規範的驅動程式會傳回 SQLSTATE HY090 (字串或緩衝區長度無效),在此情況下。

StrLen_or_IndPtr
[延後輸入/輸出]要系結至資料行之長度/指標緩衝區的指標。 SQLFetch SQLFetchScroll 會傳回這個緩衝區中的值。 當 Operation 為SQL_ADD、SQL_UPDATE_BY_BOOKMARK或SQL_DELETE_BY_BOOKMARK時 ,SQLBulkOperations 會從這個緩衝區擷取值。 當 Operation SQL_FETCH_BY_BOOKMARK 時 ,SQLBulkOperations 會傳回這個緩衝區中的值。 當 Operation SQL_REFRESH 時 ,SQLSetPos 會傳回這個緩衝區中的值;當 Operation SQL_UPDATE 時 ,它會從這個緩衝區擷取值。

SQLFetch、 SQLFetchScroll SQLBulkOperations SQLSetPos 可以在長度/指標緩衝區中傳回下列值:

  • 可供傳回之資料的長度

  • SQL_NO_TOTAL

  • SQL_NULL_DATA

應用程式可以將下列值放在長度/指標緩衝區中,以便與 SQLBulkOperations SQLSetPos 搭配 使用:

  • 所傳送資料的長度

  • 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 指標,則不會使用長度或指標值。 擷取資料且資料為 Null 時發生錯誤。

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

傳回

SQL_SUCCESS、SQL_SUCCESS_WITH_INFO、SQL_ERROR或SQL_INVALID_HANDLE。

診斷

當 SQLBindCol 傳回SQL_ERROR或SQL_SUCCESS_WITH_INFO時 ,藉由呼叫 SQLGetDiagRec handletype 為 SQL_HANDLE_STMT 和 StatementHandle 的 HandleHandle ,即可取得相關聯的 SQLSTATE 值。 下表列出 SQLBindCol 通常傳 回的 SQLSTATE 值,並說明此函式內容中的每個值;標記法 「(DM)」 在驅動程式管理員傳回的 SQLSTATEs 描述之前。 除非另有說明,否則與每個 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 呼叫 SQLExecute SQLExecDirect SQLMoreResults ,並傳回SQL_PARAM_DATA_AVAILABLE。 在擷取所有資料流程參數的資料之前,會呼叫此函式。

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

(DM) 已針對 StatementHandle 呼叫 SQLExecute SQLExecDirect SQLBulkOperations SQLSetPos ,並傳回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 可用來將結果集中的資料行與應用程式中的資料緩衝區和長度/指標緩衝區產生關聯或 系結 。 當應用程式呼叫 SQLFetch、 SQLFetchScroll SQLSetPos 來擷取 資料時,驅動程式會傳回指定緩衝區中系結資料行的資料;如需詳細資訊,請參閱 SQLFetch 函式 。 當應用程式呼叫 SQLBulkOperations 來更新或插入資料列或 SQLSetPos 以更新資料列時,驅動程式會從指定的緩衝區擷取系結資料行的資料;如需詳細資訊,請參閱 SQLBulkOperations 函 式或 SQLSetPos 函式 。 如需系結的詳細資訊,請參閱 擷取結果 (基本)

請注意,資料行不一定要系結以從中擷取資料。 應用程式也可以呼叫 SQLGetData ,從資料行擷取資料。 雖然可以系結資料列中的某些資料行,並針對其他資料行呼叫 SQLGetData ,但這受限於某些限制。 如需詳細資訊,請參閱 SQLGetData

系結、解除系結和重新系結資料行

即使從結果集擷取資料之後,資料行隨時都可以系結、未系結或反彈。 新系結會在下次呼叫使用系結的函式時生效。 例如,假設應用程式系結結果集中的資料行,並呼叫 SQLFetch 。 驅動程式會傳回系結緩衝區中的資料。 現在假設應用程式會將資料行系結至不同的緩衝區集。 驅動程式不會將剛擷取資料列的資料放入新系結緩衝區中。 相反地,它會等 到再次呼叫 SQLFetch ,然後將下一個資料列的資料放在新系結緩衝區中。

注意

在將資料行系結至資料行 0 之前,應該一律設定語句屬性SQL_ATTR_USE_BOOKMARKS。 這不是必要專案,但強烈建議使用。

繫結資料行

若要系結資料行,應用程式會呼叫 SQLBindCol ,並傳遞資料緩衝區的資料行編號、類型、位址和長度,以及長度/指標緩衝區的位址。 如需如何使用這些位址的資訊,請參閱本節稍後的。 如需系結資料行的詳細資訊,請參閱 使用 SQLBindCol

這些緩衝區的使用會延遲;也就是說,應用程式會在 SQLBindCol 系結它們,但驅動程式會從其他函式存取它們,也就是 SQLBulkOperations SQLFetch、 SQLFetchScroll SQLSetPos。 應用程式必須負責確保只要系結維持有效,SQLBindCol 中指定的 指標仍有效。 如果應用程式允許這些指標變成無效,例如,它會釋放緩衝區,然後呼叫預期這些指標有效之函式,則後果為未定義。 如需詳細資訊,請參閱 延遲緩衝區

系結會維持有效狀態,直到它被新的系結取代、資料行未系結或釋放語句為止。

解除系結資料行

若要解除系結單一資料行,應用程式會呼叫 SQLBindCol ,並將 ColumnNumber 設定為該資料行的數目,並將 TargetValuePtr 設定為 Null 指標。 如果 ColumnNumber 參考未系結的資料行, SQLBindCol 仍會傳回SQL_SUCCESS。

若要解除所有資料行的系結,應用程式會呼叫 SQLFreeStmt ,並將 fOption 設定為 SQL_UNBIND。 這也可以藉由將 ARD 的 SQL_DESC_COUNT 欄位設定為零來完成。

重新系結資料行

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

  • 呼叫 SQLBindCol ,為已經系結的資料行指定新的系結。 驅動程式會以新的系結覆寫舊的系結。

  • 指定要加入至 SQLBindCol 系結呼叫 所指定之緩衝區位址的位移。 如需詳細資訊,請參閱下一節「系結位移」。

系結位移

系結位移是值,會在取值之前新增至資料和長度/指標緩衝區的位址(如 TargetValuePtr StrLen_or_IndPtr 引數中所 指定)。 使用位移時,系結是應用程式緩衝區配置方式的「範本」,而且應用程式可以藉由變更位移,將此「範本」移至記憶體的不同區域。 由於會將相同的位移新增至每個系結中的每個位址,因此不同資料行之緩衝區之間的相對位移必須在每個緩衝區集內相同。 使用資料列式系結時,這一律為 true;當使用資料行型系結時,應用程式必須仔細配置其緩衝區,才能為 true。

使用系結位移基本上與藉由呼叫 SQLBindCol 重新系結資料行的效果相同。 差別在於,對 SQLBindCol 的新呼叫 會指定資料緩衝區和長度/指標緩衝區的新位址,而使用系結位移並不會變更位址,而只會為其新增位移。 應用程式可以在每次想要時指定新的位移,而且此位移一律會新增至原始系結位址。 特別是,如果位移設定為 0,或語句屬性設定為 Null 指標,則驅動程式會使用原始系結的位址。

若要指定系結位移,應用程式會將 SQL_ATTR_ROW_BIND_OFFSET_PTR 語句屬性設定為 SQLINTEGER 緩衝區的位址。 在應用程式呼叫使用系結的函式之前,它會在此緩衝區中以位元組為單位放置位移。 若要判斷要使用的緩衝區位址,驅動程式會將位移新增至系結中的位址。 位址和位移的總和必須是有效的位址,但加入位移的位址不一定要有效。 如需如何使用系結位移的詳細資訊,請參閱本節稍後的。

系結陣列

如果資料列集大小(SQL_ATTR_ROW_ARRAY_SIZE語句屬性的值)大於 1,則應用程式會系結緩衝區陣列,而不是單一緩衝區。 如需詳細資訊,請參閱 區塊資料指標

應用程式可以透過兩種方式系結陣列:

  • 將陣列繫結至每個資料行。 這稱為 資料行型系結 ,因為每個資料結構(陣列)都包含單一資料行的資料。

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

緩衝區的每個陣列必須至少有與資料列集大小一樣多的專案。

注意

應用程式必須確認對齊是否有效。 如需對齊考慮的詳細資訊,請參閱 對齊 方式。

資料行取向的繫結

在資料行系結中,應用程式會將不同的資料和長度/指標陣列系結至每個資料行。

若要使用資料行系結,應用程式會先將 SQL_ATTR_ROW_BIND_TYPE 語句屬性設定為 SQL_BIND_BY_COLUMN。 (這是預設值。針對要系結的每個資料行,應用程式會執行下列步驟:

  1. 配置資料緩衝區陣列。

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

    注意

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

  3. 使用下列引數呼叫 SQLBindCol

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

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

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

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

如需如何使用這項資訊的詳細資訊,請參閱本節稍後的。 如需資料行系結的詳細資訊,請參閱 資料行-Wise 系結

資料列取向的繫結

在資料列系結中,應用程式會定義結構,其中包含要系結之每個資料行的資料和長度/指標緩衝區。

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

  1. 定義結構來保存單一資料列(包括資料和長度/指標緩衝區),並配置這些結構的陣列。

    注意

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

  2. 將 SQL_ATTR_ROW_BIND_TYPE 語句屬性設定為包含單一資料列的結構大小,或設定為將系結結果資料行之緩衝區實例的大小。 長度必須包含所有系結資料行的空間,以及結構或緩衝區的任何填補,以確保當系結資料行的位址以指定的長度遞增時,結果會指向下一個資料列中相同資料行的開頭。 在 ANSI C 中使用 sizeof 運算子時,會保證此行為。

  3. 針對要系結的每個資料行,呼叫 具有下列引數的 SQLBindCol

    • TargetType 是系結至資料行的資料緩衝區成員類型。

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

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

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

如需如何使用這項資訊的詳細資訊,請參閱本節稍後的。 如需資料行系結的詳細資訊,請參閱 資料列-Wise 系結

緩衝區位址

緩衝區 位址 是資料或長度/指標緩衝區的實際位址。 驅動程式會在寫入緩衝區之前計算緩衝區位址(例如在擷取期間)。 它會從下列公式計算,它會使用 TargetValuePtr 中指定的位址 ,以及 StrLen_or_IndPtr 引數、系結位移和資料列 編號:

系結位址 + 系結位移 + (( 列號 - 1) x 元素大小)

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

變數 描述
系結位址 針對資料緩衝區,在 SQLBindCol 中使用 TargetValuePtr 引數指定的 位址。

針對長度/指標緩衝區,在 SQLBindCol 中使用 StrLen_or_IndPtr 引數指定的 位址。 如需詳細資訊,請參閱<描述項和 SQLBindCol>一節中的。

如果系結位址為 0,則不會傳回任何資料值,即使上一個公式所計算的位址不是零值也一樣。
系結位移 如果使用資料列式系結,則儲存在使用 SQL_ATTR_ROW_BIND_OFFSET_PTR 語句屬性指定之位址的值。

如果使用資料行型系結,或如果SQL_ATTR_ROW_BIND_OFFSET_PTR語句屬性的值是 Null 指標, 則 Binding Offset 為 0。
資料列號碼 資料列集中以 1 為起始的資料列數目。 如果是預設的單一資料列擷取,這是 1。
元素大小 綁定陣列中專案的大小。

如果使用資料行的系結,這是 長度/指標緩衝區的大小of(SQLINTEGER)。 如果是資料緩衝區,如果資料類型是可變長度,則為 SQLBindCol BufferLength 引數的值 ,如果資料類型是固定長度,則為資料類型的大小。

如果使用資料列式系結,這是資料與長度/指標緩衝區SQL_ATTR_ROW_BIND_TYPE語句屬性的值。

描述項和 SQLBindCol

下列各節說明 SQLBindCol 如何 與描述項互動。

警告

針對一個語句呼叫 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 是 datetime 或 interval 子類型的其中一個精簡識別碼,則會分別將SQL_DESC_TYPE設定為SQL_DATETIME或SQL_INTERVAL;將SQL_DESC_CONCISE_TYPE設定為精簡識別碼;並將SQL_DESC_DATETIME_INTERVAL_CODE設定為對應的 datetime 或 interval 子碼。

    • 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 引數所參考的變數 用於指標和長度資訊。 如果擷取遇到資料行的 Null 值,則會將SQL_Null_DATA儲存在此變數中;否則,它會將資料長度儲存在此變數中。 傳遞 null 指標做為 StrLen_or_IndPtr 會讓擷取作業不傳回資料長度,但如果擷取遇到 null 值,而且無法傳回SQL_Null_DATA,則提取會失敗。

如果對 SQLBindCol 的呼叫 失敗,則未定義在 ARD 中設定的描述元欄位內容,且 ARD 的 SQL_DESC_COUNT 欄位值保持不變。

COUNT 欄位的隱含重設

只有在這樣會增加SQL_DESC_COUNT值 時,SQLBindCol 才會將 SQL_DESC_COUNT 設定為 ColumnNumber 引數的值。 如果 TargetValuePtr 引數中的 值為 null 指標,且 ColumnNumber 引數中的 值等於 SQL_DESC_COUNT (也就是說,解除系結最高的資料行時),則SQL_DESC_COUNT會設定為剩餘上限資料行的數目。

關於SQL_DEFAULT注意事項

若要成功擷取資料行資料,應用程式必須正確判斷應用程式緩衝區中資料的長度和起點。 當應用程式指定明確的 TargetType 時,很容易偵測到應用程式誤解。 不過,當應用程式指定 SQL_DEFAULT的 TargetType 時, SQLBindCol 可以套用至與應用程式所預期之資料類型不同的資料行,從變更至中繼資料,或將程式碼套用至不同的資料行。 在此情況下,應用程式不一定會判斷所擷取資料行資料的開始或長度。 這可能會導致未報告的資料錯誤或記憶體違規。

程式碼範例

在下列範例中,應用程式會在 Customers 資料表上執行 SELECT 語句,以傳回依名稱排序之客戶識別碼、名稱和電話號碼的結果集。 然後它會呼叫 SQLBindCol ,將資料行系結至本機緩衝區。 最後,應用程式會使用 SQLFetch 擷取 每個資料列,並列印每個客戶的名稱、識別碼和電話號碼。

如需更多程式碼範例,請參閱 SQLBulkOperations 函 式、 SQLColumns 函 式、 SQLFetchScroll 函式和 SQLSetPos 函 式 。

// 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 函式

另請參閱

ODBC API 參考
ODBC 標頭檔