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
[輸入]緩衝區的指標,其中包含參數或資料行的實際資料。 資料必須位於 SQLBindParameter ValueType 引數中指定的 C 資料類型(適用于參數資料)或 SQLBindCol TargetType 引數(適用于資料行資料)。

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

  • StrLen_or_Ind 是SQL_NTS、SQL_Null_DATA或SQL_DEFAULT_PARAM。

  • 在 SQLBindParameter SQLBindCol 中指定的 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的 HandleType StatementHandle 控制碼 來取得相關聯的 SQLSTATE 值。 下表列出 SQLPutData 通常傳 回的 SQLSTATE 值,並說明此函式內容中的每個值;標記法 「(DM)」 在驅動程式管理員傳回的 SQLSTATE 描述之前。 除非另有說明,否則與每個 SQLSTATE 值相關聯的傳回碼會SQL_ERROR。

SQLSTATE 錯誤 描述
01000 一般警告 驅動程式特定的資訊訊息。 (函式會傳回SQL_SUCCESS_WITH_INFO。)
01004 字串資料,右截斷 針對輸出參數傳回的字串或二進位資料,導致截斷非空白字元或非 Null 二進位資料。 如果它是字串值,則會將其右截斷。 (函式會傳回SQL_SUCCESS_WITH_INFO。)
07006 受限制的資料類型屬性違規 系結參數之 SQLBindParameter 中 ValueType 引數所識別 的資料值無法轉換成 SQLBindParameter ParameterType 引數所識別 的資料類型。
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 上 呼叫 SQLCancel SQLCancelHandle 。 然後在 StatementHandle 再次呼叫函式。

呼叫函式,並在完成執行之前, 從多執行緒應用程式中的不同執行緒呼叫 語句Handle 或 SQLCancelHandle
HY009 不正確 Null 指標使用 (DM) 引數 DataPtr 是 null 指標,而 引數 StrLen_or_Ind 不是 0、SQL_DEFAULT_PARAM或SQL_Null_DATA。
HY010 函式順序錯誤 (DM) 先前的函式呼叫不是對 SQLPutData SQLParamData 呼叫。

(DM) 已針對與 StatementHandle 相關聯的連接控制碼呼叫非同步執行函式。 呼叫 SQLPutData 函式時,這個非同步函式仍在執行中。

(DM) 已針對 StatementHandle 呼叫 SQLExecute SQLExecDirect SQLMoreResults ,並傳回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,該 SQLSTATE 可由呼叫的函式傳回以執行語句 ( SQLExecute SQLExecDirect )。 如果在傳送要更新或加入 SQLBulkOperations 的資料行資料或以 SQLSetPos 進行更新時呼叫,它可以傳回 SQLBulkOperations SQLSetPos 可傳 回的任何 SQLSTATE。

註解

您可以呼叫 SQLPutData 來提供兩個用途的資料執行資料:呼叫 SQLExecute SQLExecDirect 要使用的參數資料,或呼叫 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 語句,也可以 處理 SQLBulkOperations SQLSetPos 呼叫。

如需如何在語句執行時間傳遞資料執行參數資料的詳細資訊,請參閱 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 標頭檔