Função SQLPutData

Conformidade
Versão introduzida: Conformidade de padrões do ODBC 1.0: ISO 92

Resumo
SQLPutData permite que um aplicativo envie dados para um parâmetro ou coluna para o driver no momento da execução da instrução. Essa função pode ser usada para enviar valores de dados binários ou de caracteres em partes para uma coluna com um tipo de dados específico de caractere, binário ou de fonte de dados (por exemplo, parâmetros do SQL_LONGVARBINARY ou tipos de SQL_LONGVARCHAR). SQLPutData dá suporte à associação a um tipo de dados Unicode C, mesmo que o driver subjacente não dê suporte a dados Unicode.

Sintaxe

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

Argumentos

StatementHandle
[Entrada] Identificador de instrução.

DataPtr
[Entrada] Ponteiro para um buffer que contém os dados reais para o parâmetro ou coluna. Os dados devem estar no tipo de dados C especificado no argumento ValueType de SQLBindParameter (para dados de parâmetro) ou no argumento TargetType de SQLBindCol (para dados de coluna).

StrLen_or_Ind
[Entrada] Comprimento de *DataPtr. Especifica a quantidade de dados enviados em uma chamada para SQLPutData. A quantidade de dados pode variar com cada chamada para um determinado parâmetro ou coluna. StrLen_or_Ind é ignorado, a menos que atenda a uma das seguintes condições:

  • StrLen_or_Ind é SQL_NTS, SQL_NULL_DATA ou SQL_DEFAULT_PARAM.

  • O tipo de dados C especificado em SQLBindParameter ou SQLBindCol é SQL_C_CHAR ou SQL_C_BINARY.

  • O tipo de dados C é SQL_C_DEFAULT e o tipo de dados C padrão para o tipo de dados SQL especificado é SQL_C_CHAR ou SQL_C_BINARY.

Para todos os outros tipos de dados C, se StrLen_or_Ind não for SQL_NULL_DATA ou SQL_DEFAULT_PARAM, o driver assumirá que o tamanho do buffer *DataPtr é o tamanho do tipo de dados C especificado com ValueType ou TargetType e envia todo o valor de dados. Para obter mais informações, consulte Convertendo dados de C para tipos de dados SQL no apêndice D: tipos de dados.

Retornos

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR ou SQL_INVALID_HANDLE.

Diagnósticos

Quando SQLPutData retorna SQL_ERROR ou SQL_SUCCESS_WITH_INFO, um valor SQLSTATE associado pode ser obtido chamando SQLGetDiagRec com um HandleType de SQL_HANDLE_STMT e um Identificador de StatementHandle. A tabela a seguir lista os valores SQLSTATE normalmente retornados por SQLPutData e explica cada um deles no contexto dessa função; a notação "(DM)" precede as descrições de SQLSTATEs retornadas pelo Gerenciador de Driver. O código de retorno associado a cada valor SQLSTATE é SQL_ERROR, a menos que indicado o contrário.

SQLSTATE Erro Descrição
01000 Aviso geral Mensagem informativa específica do driver. (A função retorna SQL_SUCCESS_WITH_INFO.)
01004 Dados de cadeia de caracteres, truncados à direita A cadeia de caracteres ou os dados binários retornados para um parâmetro de saída resultaram no truncamento de caracteres não em branco ou dados binários não NULL. Se fosse um valor de cadeia de caracteres, ele estava truncado à direita. (A função retorna SQL_SUCCESS_WITH_INFO.)
07006 Violação de atributo de tipo de dados restrito O valor de dados identificado pelo argumento ValueType em SQLBindParameter para o parâmetro associado não pôde ser convertido no tipo de dados identificado pelo argumento ParameterType em SQLBindParameter.
07S01 Uso inválido do parâmetro padrão Um valor de parâmetro, definido com SQLBindParameter, foi SQL_DEFAULT_PARAM e o parâmetro correspondente não tinha um valor padrão.
08S01 Falha no link de comunicação O link de comunicação entre o driver e a fonte de dados à qual o driver foi conectado falhou antes da função concluir o processamento.
22001 Dados de cadeia de caracteres, truncamento à direita A atribuição de um caractere ou valor binário a uma coluna resultou no truncamento de caracteres ou bytes não nulas (não nulos).

O tipo de informações SQL_NEED_LONG_DATA_LEN no SQLGetInfo era "Y" e mais dados foram enviados para um parâmetro longo (o tipo de dados foi SQL_LONGVARCHAR, SQL_LONGVARBINARY ou um tipo de dados específico da fonte de dados longa) do que foi especificado com o argumento StrLen_or_IndPtr em SQLBindParameter.

O tipo de informações SQL_NEED_LONG_DATA_LEN no SQLGetInfo era "Y" e mais dados foram enviados para uma coluna longa (o tipo de dados foi SQL_LONGVARCHAR, SQL_LONGVARBINARY ou um tipo de dados específico de fonte de dados longo) do que foi especificado no buffer de comprimento correspondente a uma coluna em uma linha de dados que foi adicionada ou atualizada com SQLBulkOperations ou atualizada com SQLSetPos.
22003 Valor numérico fora do intervalo Os dados enviados para um parâmetro numérico associado ou coluna fizeram com que a parte inteira (em vez de fracionária) do número fosse truncada quando atribuída à coluna da tabela associada.

Retornar um valor numérico (como numérico ou cadeia de caracteres) para um ou mais parâmetros de entrada/saída ou saída teria feito com que toda a parte (em vez de fracionária) do número fosse truncada.
22007 Formato de datetime inválido Os dados enviados para um parâmetro ou coluna associada a uma estrutura de data, hora ou carimbo de data/hora eram, respectivamente, uma data, hora ou carimbo de data/hora inválido.

Um parâmetro de entrada/saída ou saída foi associado a uma estrutura C de data, hora ou carimbo de data/hora e um valor no parâmetro retornado era, respectivamente, uma data, hora ou carimbo de data/hora inválido. (A função retorna SQL_SUCCESS_WITH_INFO.)
22008 Estouro de campo de datetime Uma expressão datetime computada para um parâmetro de entrada/saída ou saída resultou em uma estrutura C de data, hora ou carimbo de data/hora inválida.
22012 Divisão por zero Uma expressão aritmética calculada para um parâmetro de entrada/saída ou saída resultou em divisão por zero.
22015 Estouro de campo de intervalo Os dados enviados para uma coluna ou parâmetro numérico ou intervalo exato para um tipo de dados SQL de intervalo causaram uma perda de dígitos significativos.

Os dados foram enviados para uma coluna ou parâmetro de intervalo com mais de um campo, foram convertidos em um tipo de dados numérico e não tinham representação no tipo de dados numérico.

Os dados enviados para dados de coluna ou parâmetro foram atribuídos a um tipo SQL de intervalo e não houve representação do valor do tipo C no tipo SQL do intervalo.

Os dados enviados para uma coluna ou parâmetro C numérico exato ou intervalo para um tipo C de intervalo causaram uma perda de dígitos significativos.

Os dados enviados para dados de coluna ou parâmetro foram atribuídos a uma estrutura de intervalo C e não houve representação dos dados na estrutura de dados do intervalo.
22018 Valor de caractere inválido para especificação de conversão O tipo C era um numérico exato ou aproximado, um datetime ou um tipo de dados de intervalo; o tipo SQL da coluna era um tipo de dados de caractere; e o valor na coluna ou parâmetro não era um literal válido do tipo C associado.

O tipo SQL era um numérico exato ou aproximado, um datetime ou um tipo de dados de intervalo; o tipo C foi SQL_C_CHAR; e o valor na coluna ou parâmetro não era um literal válido do tipo SQL associado.
HY000 Erro geral Ocorreu um erro para o qual não havia nenhum SQLSTATE específico e para o qual nenhum SQLSTATE específico da implementação foi definido. A mensagem de erro retornada por SQLGetDiagRec no buffer *MessageText descreve o erro e sua causa.
HY001 Erro de alocação de memória O driver não pôde alocar a memória necessária para dar suporte à execução ou à conclusão da função.
HY008 Operação cancelada O processamento assíncrono foi habilitado para StatementHandle. A função foi chamada e, antes de concluir a execução, SQLCancel ou SQLCancelHandle foi chamado no StatementHandle. Em seguida, a função foi chamada novamente no StatementHandle.

A função foi chamada e antes de concluir a execução, SQLCancel ou SQLCancelHandle foi chamado no StatementHandle de um thread diferente em um aplicativo multithread.
HY009 Uso inválido de ponteiro nulo (DM) O argumento DataPtr era um ponteiro nulo e o argumento StrLen_or_Ind não era 0, SQL_DEFAULT_PARAM ou SQL_NULL_DATA.
HY010 Erro de sequência de funções (DM) A chamada de função anterior não era uma chamada para SQLPutData ou SQLParamData.

(DM) Uma função em execução assíncrona foi chamada para o identificador de conexão associado ao StatementHandle. Essa função assíncrona ainda estava em execução quando a função SQLPutData foi chamada.

(DM) SQLExecute, SQLExecDirect ou SQLMoreResults foi chamado para StatementHandle e retornado SQL_PARAM_DATA_AVAILABLE. Essa função foi chamada antes de os dados serem recuperados para todos os parâmetros transmitidos.

(DM) Uma função de execução assíncrona (não esta) foi chamada para StatementHandle e ainda estava em execução quando essa função foi chamada.
HY013 Erro de gerenciamento de memória A chamada de função não pôde ser processada porque os objetos de memória subjacentes não puderam ser acessados, possivelmente devido a condições de memória baixa.
HY019 Dados não caracteres e não binários enviados em partes SQLPutData foi chamado mais de uma vez para um parâmetro ou coluna e não estava sendo usado para enviar dados de caractere C para uma coluna com um tipo de dados específico de fonte de dados, binário ou caractere ou para enviar dados binários C para uma coluna com um tipo de dados específico de fonte de dados, binário ou caractere.
HY020 Tentativa de concatenar um valor nulo SQLPutData foi chamado mais de uma vez desde que a chamada que retornou SQL_NEED_DATA e, em uma dessas chamadas, o argumento StrLen_or_Ind continha SQL_NULL_DATA ou SQL_DEFAULT_PARAM.
HY090 Comprimento de buffer ou cadeia de caracteres inválido O argumento DataPtr não era um ponteiro nulo e o argumento StrLen_or_Ind era menor que 0, mas não igual a SQL_NTS ou SQL_NULL_DATA.
HY117 A conexão está suspensa devido ao estado de transação desconhecido. Somente funções desconectar e somente leitura são permitidas. (DM) Para obter mais informações sobre o estado suspenso, consulte Função SQLEndTran.
HYT01 O tempo limite da conexão expirou O período de tempo limite da conexão expirou antes da fonte de dados responder à solicitação. O período de tempo limite da conexão é definido por meio de SQLSetConnectAttr, SQL_ATTR_CONNECTION_TIMEOUT.
IM001 O driver não dá suporte a essa função (DM) O driver associado ao StatementHandle não dá suporte à função .
IM017 A sondagem está desabilitada no modo de notificação assíncrona Sempre que o modelo de notificação é usado, a sondagem é desabilitada.
IM018 SQLCompleteAsync não foi chamado para concluir a operação assíncrona anterior nesse identificador. Se a chamada de função anterior no identificador retornar SQL_STILL_EXECUTING e se o modo de notificação estiver habilitado, SQLCompleteAsync deverá ser chamado no identificador para fazer o pós-processamento e concluir a operação.

Se SQLPutData for chamado ao enviar dados para um parâmetro em uma instrução SQL, ele poderá retornar qualquer SQLSTATE que possa ser retornado pela função chamada para executar a instrução (SQLExecute ou SQLExecDirect). Se for chamado ao enviar dados para uma coluna que está sendo atualizada ou adicionada com SQLBulkOperations ou ser atualizada com SQLSetPos, ela poderá retornar qualquer SQLSTATE que possa ser retornado por SQLBulkOperations ou SQLSetPos.

Comentários

SQLPutData pode ser chamado para fornecer dados de dados em execução para dois usos: dados de parâmetro a serem usados em uma chamada para SQLExecute ou SQLExecDirect ou dados de coluna a serem usados quando uma linha é atualizada ou adicionada por uma chamada para SQLBulkOperations ou é atualizada por uma chamada para SQLSetPos.

Quando um aplicativo chama SQLParamData para determinar quais dados devem ser enviados, o driver retorna um indicador que o aplicativo pode usar para determinar quais dados de parâmetro enviar ou para onde os dados de coluna podem ser encontrados. Ele também retorna SQL_NEED_DATA, que é um indicador para o aplicativo de que ele deve chamar SQLPutData para enviar os dados. No argumento DataPtr para SQLPutData, o aplicativo passa um ponteiro para o buffer que contém os dados reais para o parâmetro ou coluna.

Quando o driver retorna SQL_SUCCESS para SQLPutData, o aplicativo chama SQLParamData novamente. SQLParamData retornará SQL_NEED_DATA se mais dados precisarem ser enviados; nesse caso, o aplicativo chamará SQLPutData novamente. Ele retornará SQL_SUCCESS se todos os dados em execução tiverem sido enviados. Em seguida, o aplicativo chama SQLParamData novamente. Se o driver retornar SQL_NEED_DATA e outro indicador em *ValuePtrPtr, ele exigirá dados para outro parâmetro ou coluna e SQLPutData será chamado novamente. Se o driver retornar SQL_SUCCESS, todos os dados em execução serão enviados e a instrução SQL poderá ser executada ou a chamada SQLBulkOperations ou SQLSetPos poderá ser processada.

Para obter mais informações sobre como os dados de parâmetro de dados em execução são passados no tempo de execução da instrução, consulte "Passando valores de parâmetro" em SQLBindParameter e Enviando dados longos. Para obter mais informações sobre como os dados da coluna de dados em execução são atualizados ou adicionados, consulte a seção "Usando SQLSetPos" em SQLSetPos, "Executando Atualizações em massa usando indicadores" em SQLBulkOperations e Dados Longos e SQLSetPos e SQLBulkOperations.

Observação

Um aplicativo pode usar SQLPutData para enviar dados em partes somente ao enviar dados de caractere C para uma coluna com um tipo de dados específico de fonte de dados, binário ou de caractere ou ao enviar dados binários C para uma coluna com um tipo de dados específico de fonte de dados, binário ou caractere. Se SQLPutData for chamado mais de uma vez em qualquer outra condição, ele retornará SQL_ERROR e SQLSTATE HY019 (dados não binários e não caracteres enviados em partes).

Exemplo

O exemplo a seguir pressupõe um nome de fonte de dados chamado Teste. O banco de dados associado deve ter uma tabela que você pode criar, da seguinte maneira:

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);  
}  
Para obter informações sobre Consulte
Associar um buffer a um parâmetro Função SQLBindParameter
Cancelando o processamento da instrução Função SQLCancel
Executando uma instrução SQL Função SQLExecDirect
Executando uma instrução SQL preparada Função SQLExecute
Retornando o próximo parâmetro para o qual enviar dados Função SQLParamData

Consulte Também

Referência de API do ODBC
Arquivos de cabeçalho ODBC