SQLPutData 函式

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

摘要
SQLPutData 可讓應用程式在語句運行時間將參數或數據行的數據傳送至驅動程式。 此函式可用來將部分中的字元或二進位數據值傳送至具有字元、二進位或數據源特定數據類型的數據行(例如,SQL_LONGVARBINARY或SQL_LONGVARCHAR類型的參數)。 SQLPutData 支援系結至 Unicode C 數據類型,即使基礎驅動程式不支援 Unicode 數據也一樣。

語法

  
SQLRETURN SQLPutData(  
      SQLHSTMT     StatementHandle,  
      SQLPOINTER   DataPtr,  
      SQLLEN       StrLen_or_Ind);  

引數

StatementHandle
[輸入]語句句柄。

DataPtr
[輸入]緩衝區的指標,其中包含參數或數據行的實際數據。 數據必須位於 SQLBindParameterValueType 自變數中指定的 C 數據類型(適用於參數數據)或 SQLBindColTargetType 自變數(適用於數據行數據)。

StrLen_or_Ind
[輸入]*DataPtr 的長度。 指定呼叫 SQLPutData 中所傳送的數據量。 數據量可能會隨著指定參數或數據行的每個呼叫而有所不同。 除非符合下列其中一個條件,否則會忽略StrLen_or_Ind:

  • StrLen_or_Ind是SQL_NTS、SQL_NULL_DATA或SQL_DEFAULT_PARAM。

  • 在 SQLBindParameterSQLBindCol 中指定的 C 數據類型是SQL_C_CHAR或SQL_C_BINARY。

  • C 資料類型是SQL_C_DEFAULT,而指定 SQL 資料類型的預設 C 資料類型是SQL_C_CHAR或SQL_C_BINARY。

對於所有其他 C 數據類型,如果StrLen_or_Ind不是SQL_NULL_DATA或SQL_DEFAULT_PARAM,驅動程式會假設 *DataPtr 緩衝區的大小是以 ValueType 或 TargetType 指定的 C 數據類型大小,並傳送整個數據值。 如需詳細資訊,請參閱 附錄 D:數據類型中的將數據從 C 轉換成 SQL 數據類型

傳回

SQL_SUCCESS、SQL_SUCCESS_WITH_INFO、SQL_STILL_EXECUTING、SQL_ERROR或SQL_INVALID_HANDLE。

診斷

SQLPutData 傳回SQL_ERROR或SQL_SUCCESS_WITH_INFO時,可以藉由呼叫 SQLGetDiagRec 搭配SQL_HANDLE_STMT的 HandleTypeStatementHandle 句柄來取得相關聯的 SQLSTATE 值。 下表列出 SQLPutData 通常傳回的 SQLSTATE 值,並說明此函式內容中的每個值;表示法 “(DM)” 在驅動程式管理員傳回的 SQLSTATE 描述之前。 除非另有說明,否則與每個 SQLSTATE 值相關聯的傳回碼會SQL_ERROR。

SQLSTATE 錯誤 描述
01000 一般警告 驅動程式特定的資訊訊息。 (函式會傳回SQL_SUCCESS_WITH_INFO。)
01004 字串數據,右截斷 針對輸出參數傳回的字串或二進位數據,導致截斷非空白字元或非 NULL 二進位數據。 如果它是字串值,則會將其右截斷。 (函式會傳回SQL_SUCCESS_WITH_INFO。)
07006 受限制的數據類型屬性違規 系結參數之 SQLBindParameter 中 ValueType 自變數所識別的數據值無法轉換成 SQLBindParameterParameterType 自變數所識別的數據類型。
07S01 預設參數的使用無效 使用 SQLBindParameter 設定的參數值已SQL_DEFAULT_PARAM,且對應的參數沒有預設值。
08S01 通訊連結失敗 驅動程式與驅動程式連線的數據源之間的通訊連結在函式完成處理之前失敗。
22001 字串數據,右截斷 將字元或二進位值指派給數據行會導致截斷非空白(字元)或非 Null(二進位)字元或位元組。

SQLGetInfo 中的SQL_NEED_LONG_DATA_LEN資訊類型是 “Y”,而且會針對 long 參數傳送更多數據(數據類型是SQL_LONGVARCHAR、SQL_LONGVARBINARY或長數據源特定數據類型),而不是在 SQLBindParameter 中使用 StrLen_or_IndPtr 自變數所指定。

SQLGetInfo 中的SQL_NEED_LONG_DATA_LEN資訊類型是 “Y”,而且會針對長數據行傳送更多數據(數據類型是SQL_LONGVARCHAR、SQL_LONGVARBINARY或長數據源特定數據類型),而不是在與 SQLBulkOperations 一起新增或更新的數據列中,或以 SQLSetPos 更新的數據列所指定的長度緩衝區中指定的數據。
22003 超出範圍的數值 針對係結數值參數或數據行傳送的數據會導致指派給相關聯數據表數據行時,將數位的整個部分(相對於小數部分)截斷。

傳回一或多個輸入/輸出或輸出參數的數值(作為數值或字串),會導致截斷數位的整個(而不是小數部分)。
22007 無效的日期時間格式 針對係結至日期、時間或時間戳結構的參數或數據行所傳送的數據,分別是無效的日期、時間或時間戳。

輸入/輸出或輸出參數係結至日期、時間或時間戳 C 結構,而傳回參數中的值分別為無效的日期、時間或時間戳。 (函式會傳回SQL_SUCCESS_WITH_INFO。)
22008 日期時間欄位溢位 針對輸入/輸出或輸出參數計算的 datetime 運算式,導致日期、時間或時間戳 C 結構無效。
22012 除以零 針對輸入/輸出或輸出參數計算的算術運算式,導致除以零。
22015 間隔欄位溢位 針對精確數值或間隔數據行或參數傳送至間隔 SQL 數據類型的數據,造成有效位數遺失。

數據會針對具有多個字段的間隔數據行或參數傳送、轉換成數值數據類型,而且數值數據類型中沒有表示。

針對數據行或參數數據傳送的數據已指派給間隔 SQL 類型,而且間隔 SQL 類型中沒有 C 型別的值表示法。

針對確切數值或間隔 C 數據行或參數傳送至間隔 C 類型的數據,造成有效位數遺失。

針對數據行或參數數據傳送的數據已指派給間隔 C 結構,而且間隔數據結構中沒有數據表示法。
22018 轉換規格的字元值無效 C 類型是精確或近似數值、日期時間或間隔數據類型;數據行的 SQL 類型是字元數據類型;和數據行或參數中的值不是系結 C 型別的有效常值。

SQL 類型是精確或近似數值、日期時間或間隔數據類型;C 類型SQL_C_CHAR;和數據行或參數中的值不是系結 SQL 類型的有效常值。
HY000 一般錯誤 發生錯誤,其中沒有特定的 SQLSTATE,也沒有定義任何實作特定的 SQLSTATE。 *MessageText 緩衝區中 SQLGetDiagRec回的錯誤訊息描述錯誤及其原因。
HY001 記憶體配置錯誤 驅動程式無法配置支援執行或完成函式所需的記憶體。
HY008 作業已取消 已針對 StatementHandle 啟用異步處理。 已呼叫函式,並在完成執行之前,在 StatementHandle 上呼叫 SQLCancelSQLCancelHandle。 然後在 StatementHandle再次呼叫函式。

呼叫函式,並在完成執行之前,從多線程應用程式中的不同線程呼叫語句Handle 或 SQLCancelHandle
HY009 無效的 Null 指標使用 (DM) 自變數 DataPtr 是 null 指標,而自變數StrLen_or_Ind不是 0、SQL_DEFAULT_PARAM或SQL_NULL_DATA。
HY010 函式順序錯誤 (DM) 先前的函數調用不是對 SQLPutDataSQLParamData呼叫。

(DM) 已針對與 StatementHandle 相關聯的連接句柄呼叫異步執行函式。 呼叫 SQLPutData 函式時,這個異步函式仍在執行中。

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

(DM) 呼叫 StatementHandle 的異步執行函式(而非此函式),並在呼叫此函式時仍在執行中。
HY013 記憶體管理錯誤 無法處理函式呼叫,因為基礎記憶體物件無法存取,可能是因為記憶體不足的情況。
HY019 以片段傳送的非字元和非二進位數據 針對參數或數據行呼叫了一次以上的 SQLPutData ,而且它不是用來將字元 C 數據傳送至具有字元、二進位或數據源特定數據類型的數據行,或是將二進位 C 數據傳送至具有字元、二進位或數據源特定數據類型的數據行。
HY020 嘗試串連 Null 值 自傳回SQL_NEED_DATA的呼叫之後,多次呼叫 SQLPutData,並在其中一個呼叫中,StrLen_or_Ind自變數包含SQL_NULL_DATA或SQL_DEFAULT_PARAM。
HY090 無效的字串或緩衝區長度 自變數 DataPtr 不是 Null 指標,而且自變數StrLen_or_Ind小於 0,但不等於SQL_NTS或SQL_NULL_DATA。
HY117 聯機因為未知的交易狀態而暫停。 只允許中斷連線和唯讀函式。 (DM) 如需暫停狀態的詳細資訊,請參閱 SQLEndTran 函式
HYT01 已超過連線逾時 在數據源回應要求之前,連線逾時期限已過期。 線上逾時期間是透過 SQLSetConnectAttr 來設定,SQL_ATTR_CONNECTION_TIMEOUT。
IM001 驅動程式不支援此函式 (DM) 與 StatementHandle 相關聯的驅動程式不支援 函式。
IM017 在異步通知模式中停用輪詢 每當使用通知模型時,輪詢就會停用。
IM018 尚未呼叫 SQLCompleteAsync ,以完成此句柄上的先前異步操作。 如果句柄上的上一個函式呼叫傳回SQL_STILL_EXECUTING且啟用通知模式, 則必須在句柄上呼叫 SQLCompleteAsync ,才能執行後續處理並完成作業。

如果在 SQL 語句中傳送參數的數據時呼叫 SQLPutData ,它可以傳回由呼叫的函式傳回的任何 SQLSTATE 來執行語句 (SQLExecuteSQLExecDirect)。 如果在傳送要更新或加入 SQLBulkOperations 的數據行數據或以 SQLSetPos 進行更新時呼叫,它可以傳回 SQLBulkOperationsSQLSetPos 可傳回的任何 SQLSTATE。

註解

您可以呼叫 SQLPutData 來提供兩個用途的數據執行數據:呼叫 SQLExecuteSQLExecDirect要使用的參數數據,或呼叫 SQLBulkOperations 或呼叫 SQLSetPos所要使用的數據行數據。

當應用程式呼叫 SQLParamData 來判斷它應該傳送的數據時,驅動程式會傳回指標,指出應用程式可用來判斷要傳送的參數數據,或可在何處找到數據行數據。 它也會傳回SQL_NEED_DATA,這是應用程式應該呼叫 SQLPutData 來傳送數據的指標。 在 DataPtr 自變數中SQLPutData 的應用程式會將指標傳遞至緩衝區,其中包含參數或數據行的實際數據。

當驅動程式傳回 SQLPutData 的SQL_SUCCESS時,應用程式會再次呼叫 SQLParamData 如果需要傳送更多數據,SQLParamData 會傳回SQL_NEED_DATA,在此情況下,應用程式會再次呼叫 SQLPutData 。 如果已傳送所有數據執行中數據,則會傳回SQL_SUCCESS。 然後,應用程式會再次呼叫 SQLParamData 。 如果驅動程式傳回SQL_NEED_DATA和 *ValuePtrPtr 中的另一個指標,則需要另一個參數或數據行的數據,並再次呼叫 SQLPutData 如果驅動程式傳回SQL_SUCCESS,則會傳送所有數據執行中數據,而且可以執行 SQL 語句,也可以 處理 SQLBulkOperationsSQLSetPos 呼叫。

如需如何在語句運行時間傳遞數據執行參數數據的詳細資訊,請參閱 SQLBindParameter 中的傳送長數據。 如需如何更新或新增數據執行數據行數據的詳細資訊,請參閱 SQLSetPos 中的<使用 SQLSetPos>一節、SQLBulkOperations 中的,以及 Long Data 和 SQLSetPos 和 SQLBulkOperations

注意

應用程式只有在將字元 C 資料傳送至具有字元、二進位或數據源特定數據類型的數據行,或是將二進位 C 資料傳送至具有字元、二進位或數據源特定數據類型的數據行時,才能使用 SQLPutData 將數據傳送至元件中的數據。 如果在 任何其他情況下多次呼叫 SQLPutData ,則會傳回 SQL_ERROR 和 SQLSTATE HY019 (以片段傳送的非字元和非二進位數據)。

範例

下列範例假設數據源名稱稱為 Test。 相關聯的資料庫應該有您可以建立的數據表,如下所示:

CREATE TABLE emp4 (NAME char(30), AGE int, BIRTHDAY datetime, Memo1 text)  
// SQLPutData.cpp  
// compile with: odbc32.lib user32.lib  
#include <stdio.h>  
#include <windows.h>  
#include <sqlext.h>  
#include <odbcss.h>  
  
#define TEXTSIZE  12000  
#define MAXBUFLEN 256  
  
SQLHENV henv = SQL_NULL_HENV;  
SQLHDBC hdbc1 = SQL_NULL_HDBC;       
SQLHSTMT hstmt1 = SQL_NULL_HSTMT;  
  
void Cleanup() {  
   if (hstmt1 != SQL_NULL_HSTMT)  
      SQLFreeHandle(SQL_HANDLE_STMT, hstmt1);  
  
   if (hdbc1 != SQL_NULL_HDBC) {  
      SQLDisconnect(hdbc1);  
      SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);  
   }  
  
   if (henv != SQL_NULL_HENV)  
      SQLFreeHandle(SQL_HANDLE_ENV, henv);  
}  
  
int main() {  
   RETCODE retcode;  
  
   // SQLBindParameter variables.  
   SQLLEN cbTextSize, lbytes;  
  
   // SQLParamData variable.  
   PTR pParmID;  
  
   // SQLPutData variables.  
   UCHAR  Data[] =   
      "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"  
      "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"  
      "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"  
      "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"  
      "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"  
      "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"  
      "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"  
      "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"  
      "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"  
      "abcdefghijklmnopqrstuvwxyz";  
  
   SDWORD cbBatch = (SDWORD)sizeof(Data) - 1;  
  
   // Allocate the ODBC environment and save handle.  
   retcode = SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv);  
   if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {  
      printf("SQLAllocHandle(Env) Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Notify ODBC that this is an ODBC 3.0 app.  
   retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER);  
   if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {  
      printf("SQLSetEnvAttr(ODBC version) Failed\n\n");  
      Cleanup();  
      return(9);      
   }  
  
   // Allocate ODBC connection handle and connect.  
   retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1);  
   if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {  
      printf("SQLAllocHandle(hdbc1) Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Sample uses Integrated Security, create SQL Server DSN using Windows NT authentication.   
   retcode = SQLConnect(hdbc1, (UCHAR*)"Test", SQL_NTS, (UCHAR*)"",SQL_NTS, (UCHAR*)"", SQL_NTS);  
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLConnect() Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Allocate statement handle.  
   retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc1, &hstmt1);  
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLAllocHandle(hstmt1) Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Set parameters based on total data to send.  
   lbytes = (SDWORD)TEXTSIZE;  
   cbTextSize = SQL_LEN_DATA_AT_EXEC(lbytes);  
  
   // Bind the parameter marker.  
   retcode = SQLBindParameter (hstmt1,           // hstmt  
                               1,                // ipar  
                               SQL_PARAM_INPUT,  // fParamType  
                               SQL_C_CHAR,       // fCType  
                               SQL_LONGVARCHAR,  // FSqlType  
                               lbytes,           // cbColDef  
                               0,                // ibScale  
                               (VOID *)1,        // rgbValue  
                               0,                // cbValueMax  
                               &cbTextSize);     // pcbValue  
  
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLBindParameter Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Execute the command.  
   retcode =   
      SQLExecDirect(hstmt1, (UCHAR*)"INSERT INTO emp4 VALUES('Paul Borm', 46,'1950-11-12 00:00:00', ?)", SQL_NTS);  
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_NEED_DATA) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLExecDirect Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Check to see if NEED_DATA; if yes, use SQLPutData.  
   retcode = SQLParamData(hstmt1, &pParmID);  
   if (retcode == SQL_NEED_DATA) {  
      while (lbytes > cbBatch) {  
         SQLPutData(hstmt1, Data, cbBatch);  
         lbytes -= cbBatch;  
      }  
      // Put final batch.  
      retcode = SQLPutData(hstmt1, Data, lbytes);   
   }  
  
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLParamData Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Make final SQLParamData call.  
   retcode = SQLParamData(hstmt1, &pParmID);  
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("Final SQLParamData Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Clean up.  
   SQLFreeHandle(SQL_HANDLE_STMT, hstmt1);  
   SQLDisconnect(hdbc1);  
   SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);  
   SQLFreeHandle(SQL_HANDLE_ENV, henv);  
}  
如需下列資訊 請參閱
將緩衝區系結至參數 SQLBindParameter 函式
取消語句處理 SQLCancel 函式
執行 SQL 語句 SQLExecDirect 函式
執行備妥的 SQL 語句 SQLExecute 函式
傳回要傳送數據的下一個參數 SQLParamData 函式

另請參閱

ODBC API 參考
ODBC 標頭檔