使用參數陣列

若要使用參數陣列,應用程式會使用 SQL_ATTR_PARAMSET_SIZE 的 Attribute 引數呼叫 SQLSetStmtAttr,以指定參數集的數目。 它會使用 SQL_ATTR_PARAMS_PROCESSED_PTR 的 Attribute 引數呼叫 SQLSetStmtAttr,以指定變數的位址,其中驅動程式可以傳回已處理的參數集數目 (包括錯誤集)。 它會使用 SQL_ATTR_PARAM_STATUS_PTR 的 Attribute 引數呼叫 SQLSetStmtAttr 以指向陣列,其中會傳回每個參數值資料列的狀態資訊。 驅動程式會將這些位址儲存在它為陳述式維護的結構中。

注意

在 ODBC 2.x 中,已呼叫 SQLParamOptions 來指定參數的多個值。 在 ODBC 3.x 中,針對 SQLParamOptions 的呼叫已由呼叫 SQLSetStmtAttr 取代,以設定SQL_ATTR_PARAMSET_SIZE 和 SQL_ATTR_PARAMS_PROCESSED_ARRAY 屬性。

在執行陳述式之前,應用程式會設定各繫結陣列中每個元素的值。 執行陳述式時,驅動程式會使用儲存的資訊來擷取參數值,並將其傳送至資料來源;可能的話,驅動程式應該會將這些值以陣列形式進行傳送。 雖然使用陣列參數的方式,最好是透過單一呼叫搭配陣列中的所有參數執行 SQL 陳述式來加以實作,但目前在 DBMS 中並未廣泛提供這項功能。 不過,驅動程式可以藉由多次執行 SQL 陳述式 (每次都有一組參數) 來模擬這種方式。

在應用程式使用參數陣列之前,它必須確定應用程式所使用的驅動程式支援它們。 作法有二:

  • 僅使用已知驅動程式來支援參數陣列。 應用程式可以硬式編碼這些驅動程式的名稱,或指示使用者只使用這些驅動程式。 自訂應用程式和垂直應用程式通常會使用一組有限的驅動程式。

  • 在執行階段檢查參數陣列的支援。 如果可以將 SQL_ATTR_PARAMSET_SIZE 陳述式屬性設定為大於 1 的值,驅動程式就會支援參數陣列。 一般應用程式和垂直應用程式通常會在執行階段檢查是否支援參數陣列。

參數化執行中的資料列計數和結果集可用性,可透過使用 SQL_PARAM_ARRAY_ROW_COUNTS 和 SQL_PARAM_ARRAY_SELECTS 選項呼叫 SQLGetInfo 來決定。 針對 INSERTUPDATEDELETE 陳述式,SQL_PARAM_ARRAY_ROW_COUNTS 選項會指出個別資料列計數 (每個參數集各一個) 是否可用 (SQL_PARC_BATCH),或資料列計數是否匯總成一個 (SQL_PARC_NO_BATCH)。 針對 SELECT 陳述式,SQL_PARAM_ARRAY_SELECTS 選項會指出是否每個參數集 (SQL_PAS_BATCH) 都可使用結果集,還是只有一個結果集可供使用 (SQL_PAS_NO_BATCH)。 如果驅動程式不允許使用參數陣列執行結果集產生陳述式,SQL_PARAM_ARRAY_SELECTS 會傳回 SQL_PAS_NO_SELECT。 參數陣列是否可以搭配其他類型的陳述式使用,這都是資料來源特定,特別是因為這些陳述式中的參數使用會是資料來源特定,而且不會遵循 ODBC SQL 文法。

SQL_ATTR_PARAM_OPERATION_PTR 陳述式屬性所指向的陣列,可用來忽略參數的資料列。 如果陣列的元素設定為 SQL_PARAM_IGNORE,則會從 SQLExecuteSQLExecDirect 呼叫中排除對應至該元素的參數集。 SQL_ATTR_PARAM_OPERATION_PTR 屬性所指向的陣列是由應用程式配置並填入,並由驅動程式讀取。 如果擷取的資料列做為輸入參數,則資料列狀態陣列的值可以在參數作業陣列中使用。

處理時發生錯誤

如果執行陳述式時發生錯誤,執行函式會傳回錯誤,並將資料列編號變數設定為包含錯誤的資料列數目。 不論是否執行錯誤集以外的所有資料列,還是執行錯誤集之前 (但非之後) 的所有資料列,都是資料來源特定。 因為驅動程式會處理參數集,所以它會將 SQL_ATTR_PARAMS_PROCESSED_PTR 陳述式屬性所指定的緩衝區,設定為目前正在處理的資料列數目。 如果執行錯誤集以外的所有集合,驅動程式會在處理所有資料列之後,將此緩衝區設定為 SQL_ATTR_PARAMSET_SIZE。

如果已設定 SQL_ATTR_PARAM_STATUS_PTR 陳述式屬性,SQLExecuteSQLExecDirect 會傳回參數狀態陣列,以提供每個參數集的狀態。 參數狀態陣列是由應用程式所配置,並由驅動程式填入。 其元素會指出 SQL 陳述式是針對參數資料列成功執行,還是處理參數集時發生錯誤。 如果發生錯誤,驅動程式會將參數狀態陣列中的對應值設定為 SQL_PARAM_ERROR,並傳回 SQL_SUCCESS_WITH_INFO。 應用程式可以檢查狀態陣列,以判斷哪些資料列已經過處理。 使用資料列編號時,應用程式通常會更正錯誤並繼續處理。

參數狀態陣列的使用方式,取決於呼叫 SQLGetInfo 所傳回的 SQL_PARAM_ARRAY_ROW_COUNTS and SQL_PARAM_ARRAY_SELECTS 選項。 針對 INSERTUPDATEDELETE 陳述式,如果針對 SQL_PARAM_ARRAY_ROW_COUNTS 傳回 SQL_PARC_BATCH,則參數狀態陣列會填入狀態資訊,但如果傳回 SQL_PARC_NO_BATCH,則不會填入。 針對 SELECT 陳述式,如果 SQL_PARAM_ARRAY_SELECT 傳回 SQL_PAS_BATCH,則會填入參數狀態陣列,但如果傳回 SQL_PAS_NO_BATCH 或傳回 SQL_PAS_NO_SELECT,則不會填入。

資料執行中參數

如果長度/指標陣列中的任何值為 SQL_DATA_AT_EXEC,或是 SQL_LEN_DATA_AT_EXEC(length) 巨集的結果,則會使用 SQLPutData 以一般方式傳送這些值的資料。 此流程的以下方面需要特別說明,因為它們並不明顯:

  • 當驅動程式傳回 SQL_NEED_DATA 時,它必須將資料列編號變數的位址設定為需要資料的資料列。 如同單一值案例,應用程式無法對驅動程式在單一參數集中要求參數值的順序進行任何假設。 如果執行資料執行中參數時發生錯誤,SQL_ATTR_PARAMS_PROCESSED_PTR 陳述式屬性所指定的緩衝區會設定為發生錯誤的資料列數目,SQL_ATTR_PARAM_STATUS_PTR 陳述式屬性所指定的資料列狀態陣列中的資料列狀態會設定為 SQL_PARAM_ERROR,且 SQLExecuteSQLExecDirectSQLParamDataSQLPutData 的呼叫會傳回 SQL_ERROR。 如果 SQLExecuteSQLExecDirectSQLParamData 傳回 SQL_STILL_EXECUTING,則尚未定義此緩衝區的內容。

  • 由於驅動程式不會解譯 SQLBindParameterParameterValuePtr 引數中用於資料執行中參數的值,因此如果應用程式提供陣列的指標,SQLParamData 就不會擷取此陣列的元素,並將其傳回給應用程式。 相反地,它會傳回應用程式所提供的純量值。 這表示 SQLParamData 傳回的值不足以指定應用程式需要傳送資料的參數;應用程式也需要考慮目前的資料列編號。

    當只有參數陣列的某些元素是資料執行中參數時,應用程式才必須在 ParameterValuePtr 中傳遞包含所有參數元素的陣列位址。 這個陣列通常是針對非資料執行中參數的參數解譯。 針對資料執行中參數,SQLParamData 提供給應用程式的值 (通常可用來識別驅動程式在此情況下要求的資料) 一律是陣列的位址。