Поделиться через


SQLPutData, функция

Соответствие
Представлена версия: соответствие стандартам ODBC 1.0: ISO 92

Сводка
SQLPutData позволяет приложению отправлять данные для параметра или столбца драйверу во время выполнения инструкции. Эту функцию можно использовать для отправки символьных или двоичных значений данных в столбцы с типом данных, двоичным или двоичным источником данных (например, параметрами SQL_LONGVARBINARY или типами SQL_LONGVARCHAR). SQLPutData поддерживает привязку к типу данных ЮникодА C, даже если базовый драйвер не поддерживает данные Юникода.

Синтаксис

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

Аргументы

ОператорHandle
[Входные данные] Дескриптор инструкции.

DataPtr
[Входные данные] Указатель на буфер, содержащий фактические данные для параметра или столбца. Данные должны находиться в типе данных C, указанном в аргументе ValueType SQLBindParameter (для данных параметров) или аргументе TargetType SQLBindCol (для данных столбцов).

StrLen_or_Ind
[Входные данные] Длина *DataPtr. Указывает объем данных, отправленных в вызове SQLPutData. Объем данных может отличаться при каждом вызове заданного параметра или столбца. StrLen_or_Ind игнорируется, если он не соответствует одному из следующих условий:

  • StrLen_or_Ind SQL_NTS, SQL_NULL_DATA или SQL_DEFAULT_PARAM.

  • Тип данных C, указанный в SQLBindParameter или SQLBindCol , SQL_C_CHAR или SQL_C_BINARY.

  • Тип данных C — SQL_C_DEFAULT, а тип данных C по умолчанию для указанного типа данных SQL — SQL_C_CHAR или SQL_C_BINARY.

Для всех других типов данных C, если StrLen_or_Ind не SQL_NULL_DATA или SQL_DEFAULT_PARAM, драйвер предполагает, что размер буфера *DataPtr является размером типа данных C, указанного с помощью ValueType или TargetType , и отправляет все значение данных. Дополнительные сведения см. в разделе "Преобразование данных из C в типы данных SQL" в приложении D: Типы данных.

Возвраты

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR или SQL_INVALID_HANDLE.

Диагностика

Когда SQLPutData возвращает SQL_ERROR или SQL_SUCCESS_WITH_INFO, связанное значение SQLSTATE можно получить путем вызова SQLGetDiagRec с помощью HandleType SQL_HANDLE_STMT и handle of StatementHandle. В следующей таблице перечислены значения SQLSTATE, которые обычно возвращаются SQLPutData и объясняются каждый из них в контексте этой функции. Нотация "(DM)" предшествует описаниям SQLSTATEs, возвращаемым диспетчером драйверов. Возвращаемый код, связанный с каждым значением SQLSTATE, SQL_ERROR, если не указано иное.

SQLSTATE Ошибка Описание
01000 Общее предупреждение Информационное сообщение для конкретного драйвера. (Функция возвращает SQL_SUCCESS_WITH_INFO.)
01004 Строковые данные, усеченные справа Строковые или двоичные данные, возвращаемые для выходного параметра, привели к усечению небланковых символов или двоичных данных, отличных от NULL. Если это строковое значение, оно было усечено по правому краю. (Функция возвращает SQL_SUCCESS_WITH_INFO.)
07006 Нарушение атрибута ограниченного типа данных Значение данных, определяемое аргументом ValueType в SQLBindParameter для связанного параметра, не может быть преобразовано в тип данных, определенный аргументом ParameterType в SQLBindParameter.
07S01 Недопустимое использование параметра по умолчанию Значение параметра, заданное с помощью SQLBindParameter, было SQL_DEFAULT_PARAM, а соответствующий параметр не имеет значения по умолчанию.
08S01 Сбой связи Связь между драйвером и источником данных, к которому был подключен драйвер, произошел сбой до завершения обработки функции.
22001 Строковые данные, правое усечение Назначение символа или двоичного значения столбцу привело к усечению небланковых (символов) или непустых (двоичных) символов или байтов.

Тип сведений SQL_NEED_LONG_DATA_LEN в SQLGetInfo был "Y", а дополнительные данные были отправлены для длинного параметра (тип данных был SQL_LONGVARCHAR, SQL_LONGVARBINARY или длинный тип данных для конкретного источника данных), чем был указан с аргументом StrLen_or_IndPtr в SQLBindParameter.

Тип сведений SQL_NEED_LONG_DATA_LEN в SQLGetInfo был "Y", и больше данных было отправлено для длинного столбца (тип данных был SQL_LONGVARCHAR, SQL_LONGVARBINARY или длинный тип данных для конкретного источника данных), чем был указан в буфере длины, соответствующего столбцу в строке данных, которые были добавлены или обновлены с помощью SQLBulkOperations или обновлены с помощью SQLSetPos.
22003 Числовое значение вне диапазона Данные, отправленные для привязанного числового параметра или столбца, привели ко всей части (в отличие от дробной) части числа, усеченной при назначении связанному столбцу таблицы.

Возвращая числовое значение (как числовое или строковое) для одного или нескольких входных или выходных параметров, было бы вызвано усечение всей части (в отличие от дробной) части числа.
22007 Недопустимый формат datetime Данные, отправляемые для параметра или столбца, привязанного к структуре даты, времени или метки времени, соответственно, были недопустимыми датой, временем или меткой времени.

Входной или выходной параметр привязан к структуре даты, времени или метки времени, а значение в возвращаемом параметре было соответственно недопустимой датой, временем или меткой времени. (Функция возвращает SQL_SUCCESS_WITH_INFO.)
22008 Переполнение поля Datetime Выражение даты и времени, вычисленное для входного или выходного параметра, привело к недопустимой структуре даты, времени или метки времени.
22012 Деление по нулю Арифметическое выражение, вычисляемое для входного или выходного параметра, приводит к делении на нулю.
22015 Переполнение поля интервала Данные, отправленные для точного числового или интервалного столбца или параметра в тип данных SQL интервала, привели к потере значительных цифр.

Данные были отправлены для столбца интервала или параметра с несколькими полями, преобразованы в числовый тип данных и не имели представления в числовом типе данных.

Данные, отправленные для данных столбца или параметра, были назначены типу SQL интервала, и не было представления значения типа C в типе SQL интервала.

Данные, отправленные для точного числового или интервалного столбца C или параметра в тип C интервала, привели к потере значительных цифр.

Данные, отправленные для данных столбца или параметра, были назначены структуре интервала C, и в структуре данных интервала не было представления данных.
22018 Недопустимое значение символа для спецификации приведения Тип C был точным или приблизительным числом, датой и временем или типом данных интервала; Тип SQL столбца — символьный тип данных; значение столбца или параметра не является допустимым литералом привязанного типа C.

Тип SQL был точным или приблизительным числом, датой и временем или типом данных интервала; Тип C был SQL_C_CHAR; значение столбца или параметра не является допустимым литералом связанного типа SQL.
HY000 Общая ошибка Произошла ошибка, для которой не было определенного SQLSTATE и для которого не было определено значение SQLSTATE для конкретной реализации. Сообщение об ошибке, возвращаемое SQLGetDiagRec в буфере *MessageText , описывает ошибку и ее причину.
HY001 Ошибка выделения памяти Драйверу не удалось выделить память, необходимую для поддержки выполнения или завершения функции.
HY008 Операция отменена Асинхронная обработка была включена для ОператораHandle. Функция была вызвана и до завершения выполнения, SQLCancel или SQLCancelHandle была вызвана на ОператорHandle. Затем функция снова была вызвана на ОператорHandle.

Функция была вызвана и до завершения выполнения SQLCancel или SQLCancelHandle была вызвана оператором StatementHandle из другого потока в многопотоковом приложении.
HY009 Недопустимое использование указателя NULL (DM) Аргумент DataPtr был пустым указателем, и аргумент StrLen_or_Ind не был 0, SQL_DEFAULT_PARAM или SQL_NULL_DATA.
HY010 Ошибка последовательности функций (DM) Предыдущий вызов функции не был вызовом SQLPutData или SQLParamData.

(DM) Асинхронно выполняющаяся функция была вызвана для дескриптора соединения, связанного с ОператоромHandle. Эта асинхронная функция по-прежнему выполнялась при вызове функции SQLPutData.

(DM) SQLExecute, SQLExecDirect или SQLMoreResults был вызван для ОператораHandle и возвращен SQL_PARAM_DATA_AVAILABLE. Эта функция была вызвана до получения данных для всех потоковых параметров.

(DM) асинхронно выполняющаяся функция (не эта) была вызвана для StatementHandle и по-прежнему выполнялась при вызове этой функции.
HY013 Ошибка управления памятью Не удалось обработать вызов функции, так как к базовым объектам памяти не удалось получить доступ, возможно, из-за низкой памяти.
HY019 Неявные и не двоичные данные, отправляемые в фрагментах SQLPutData был вызван несколько раз для параметра или столбца, и он не использовался для отправки символьных данных C в столбец с символом, двоичным или определенным типом данных источника данных или отправлять двоичные данные C в столбец с символом, двоичным или определенным типом данных источника данных.
HY020 Попытка объединения значения NULL SQLPutData был вызван несколько раз с момента вызова, возвращающего SQL_NEED_DATA, и в одном из этих вызовов аргумент StrLen_or_Ind содержал SQL_NULL_DATA или SQL_DEFAULT_PARAM.
HY090 Недопустимая длина строки или буфера Аргумент DataPtr не был пустым указателем , а аргумент StrLen_or_Ind меньше 0, но не равен SQL_NTS или SQL_NULL_DATA.
HY117 Подключение приостановлено из-за неизвестного состояния транзакции. Разрешены только функции отключения и только для чтения. (DM) Дополнительные сведения о приостановленном состоянии см. в статье SQLEndTran Function.
HYT01 Время ожидания для подключения истекло Срок ожидания подключения истек до того, как источник данных ответил на запрос. Период времени ожидания подключения задается через SQLSetConnectAttr SQL_ATTR_CONNECTION_TIMEOUT.
IM001 Драйвер не поддерживает эту функцию (DM) Драйвер, связанный с StatementHandle , не поддерживает функцию.
IM017 Опрос отключен в асинхронном режиме уведомлений При использовании модели уведомлений опрос отключается.
IM018 SQLCompleteAsync не был вызван для выполнения предыдущей асинхронной операции с этим дескриптором. Если предыдущий вызов функции дескриптора возвращает SQL_STILL_EXECUTING и если включен режим уведомлений, sqlCompleteAsync должен вызываться на дескрипторе для выполнения последующей обработки и завершения операции.

Если SQLPutData вызывается при отправке данных для параметра в инструкции SQL, он может возвращать любой SQLSTATE, который может быть возвращен функцией, вызываемой для выполнения инструкции (SQLExecute или SQLExecDirect). Если он вызывается при отправке данных для столбца, обновляемого или добавляемого с помощью SQLBulkOperations или обновляемого с помощью SQLSetPos, он может возвращать любой SQLSTATE, который может быть возвращен SQLBulkOperations или SQLSetPos.

Комментарии

SQLPutData можно вызывать для предоставления данных во время выполнения данных для двух используемых: данные параметров, которые будут использоваться в вызове SQLExecute или SQLExecDirect, или данные столбцов, которые будут использоваться при обновлении строки или добавлении вызова SQLBulkOperations или обновляется вызовом SQLSetPos.

Когда приложение вызывает SQLParamData , чтобы определить, какие данные следует отправлять, драйвер возвращает индикатор, который приложение может использовать для определения данных параметров для отправки или расположения данных столбцов. Он также возвращает SQL_NEED_DATA, который является индикатором для приложения, которое должно вызывать SQLPutData для отправки данных. В аргументе DataPtr в SQLPutData приложение передает указатель на буфер, содержащий фактические данные для параметра или столбца.

Когда драйвер возвращает SQL_SUCCESS для SQLPutData, приложение снова вызывает SQLParamData . SQLParamData возвращает SQL_NEED_DATA, если требуется отправить больше данных, в этом случае приложение снова вызывает SQLPutData . Он возвращает SQL_SUCCESS, если отправлены все данные во время выполнения. Затем приложение снова вызывает SQLParamData . Если драйвер возвращает SQL_NEED_DATA и другой индикатор в *ValuePtrPtrPtr, он требует данных для другого параметра или столбца, а SQLPutData вызывается снова. Если драйвер возвращает SQL_SUCCESS, то все данные во время выполнения отправлены, а инструкция SQL может быть выполнена, или вызов SQLBulkOperations или SQLSetPos можно обработать.

Дополнительные сведения о передаче данных параметра во время выполнения инструкции см. в разделе "Передача значений параметров" в SQLBindParameter и отправке длинных данных. Дополнительные сведения о том, как данные столбца при выполнении обновляются или добавляются, см. в разделе "Использование SQLSetPos" в SQLSetPos, "Выполнение массовых обновлений с помощью закладок" в SQLBulkOperations, а также long Data и SQLSetPos и SQLBulkOperations.

Примечание.

Приложение может использовать SQLPutData для отправки данных в части только при отправке символьных данных C в столбец с типом данных, двоичным или двоичным типом данных или при отправке двоичных данных C в столбец с символом, двоичным или конкретным типом данных источника данных. Если 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

См. также

Справочник по API ODBC
Файлы заголовков ODBC