分享方式:


長資料和 SQLSetPos 與 SQLBulkOperations

如同 SQL 陳述式中的參數,當透過 SQLBulkOperationsSQLSetPos 更新資料列,或是過 SQLBulkOperations 插入資料列時,可以傳送長資料。 資料會分成多段,並多次呼叫 SQLPutData 來傳送。 在執行時間傳送資料的資料行就是所謂的「資料執行中資料行」。

注意

應用程式實際上可以使用 SQLPutData 在執行時間傳送任何類型的資料,雖然只有字元和二進位資料可以分段傳送。 不過,如果資料夠小而足以容納在單一緩衝區中,通常就沒有理由使用 SQLPutData。 繫結緩衝區,並讓驅動程式從緩衝區擷取資料是更為容易的作法。

因為長資料行通常不會繫結,所以應用程式必須在呼叫 SQLBulkOperationsSQLSetPos 之前繫結資料行,並在呼叫 SQLBulkOperationsSQLSetPos 之後解除繫結。 資料行必須繫結,因為 SQLBulkOperationsSQLSetPos 只會在繫結的資料行上運作,但也必須解除繫結,才能用 SQLGetData 從資料行擷取資料。

若要在執行時間傳送資料,應用程式會執行下列動作:

  1. 在資料列集緩衝區中放置一個 32 位元值,而非資料值。 此值稍後會傳回給應用程式,因此應用程式應將其設為有意義的數值,如資料行數目或包含資料的檔案控制代碼。

  2. 將長度/指標緩衝區中的值設為 SQL_LEN_DATA_AT_EXEC (長度) 巨集的結果。 此數值向驅動程式表示會使用 SQLPutData 傳送參數的資料。 「長度」值是在向資料來源傳送長資料時使用,資料來源需要知道要傳送多少個長資料位元組,以便預先配置空間。 若要判斷資料來源是否需要此值,應用程式會用 SQL_NEED_LONG_DATA_LEN 選項呼叫 SQLGetInfo。 所有驅動程式都必須支援此巨集;如果資料來源不需要位元組長度,則驅動程式可以忽略它。

  3. 呼叫 SQLBulkOperationsSQLSetPos。 驅動程式發現長度/指標緩衝區包含 SQL_LEN_DATA_AT_EXEC (長度) 巨集的結果,並傳回 SQL_NEED_DATA 作為函式的傳回值。

  4. 呼叫 SQLParamData 以回應 SQL_NEED_DATA 傳回值。 如果需要傳送長資料,SQLParamData 會傳回 SQL_NEED_DATA。 在 ValuePtrPtr 引數所指向的緩衝區中,驅動程式會傳回應用程式放在資料列集緩衝區中的唯一值。 如果資料執行中資料行有一個以上,則應用程式會利用此值來判斷要為哪個資料行傳送資料;驅動程式不需要以任何特定順序來要求資料執行中資料行的資料。

  5. 呼叫 SQLPutData 以將資料行資料傳送至驅動程式。 如果資料行資料無法納入單一緩衝區 (長資料很常發生此情形),則應用程式會重複呼叫 SQLPutData,以分段傳送資料;由驅動程式和資料來源來重新組合資料。 如果應用程式傳遞以 null 終止的字串資料,驅動程式或資料來源必須在重新組合流程中移除 null 終止字元。

  6. 再次呼叫 SQLParamData 來指出已傳送資料行的所有資料。 如果還有未傳送資料的資料執行中資料行,驅動程式會傳回 SQL_NEED_DATA 和下一個資料執行中資料行的唯一值;應用程式會回到步驟 5。 如果所有資料執行中資料行皆已傳送資料,則表示資料列的資料已傳送至資料來源。 接下來,SQLParamData 會傳回 SQL_SUCCESS 或 SQL_SUCCESS_WITH_INFO,而且可以傳回 SQLBulkOperationsSQLSetPos 可傳回的任何 SQLSTATE。

SQLBulkOperationsSQLSetPos 傳回 SQL_NEED_DATA 之後,且在給最後一個資料執行中資料行的資料完全傳送之前,陳述式會處於「需要資料」狀態。 在這個狀態下,應用程式只能呼叫 SQLPutDataSQLParamDataSQLCancelSQLGetDiagFieldSQLGetDiagRec;其他函式都會傳回 SQLSTATE HY010 (函式序列錯誤)。 呼叫 SQLCancel 會取消陳述式的執行,並返回至其先前的狀態。 如需詳細資訊,請參閱附錄 B:ODBC 狀態轉換資料表