Função SQLPutData

Conformidade
Versão Introduzida: Normas ODBC 1.0 Conformidade: ISO 92

Summary
O SQLPutData permite que uma aplicação envie dados de um parâmetro ou coluna para o driver no momento da execução da instrução. Esta função pode ser usada para enviar valores de dados de caracteres ou binários em partes para uma coluna com um tipo de dado de carácter, binário ou específico da fonte de dados (por exemplo, parâmetros dos tipos SQL_LONGVARBINARY ou SQL_LONGVARCHAR). O SQLPutData suporta binding a um tipo de dado Unicode C, mesmo que o driver subjacente não suporte dados Unicode.

Syntax

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

Arguments

HandleStatement
[Entrada] Identificador do extrato.

DataPtr
[Entrada] Apontador para um buffer contendo os dados reais do parâmetro ou coluna. Os dados devem estar no tipo de dados C especificado no argumento ValueType do SQLBindParameter (para dados de parâmetros) ou no argumento TargetType do SQLBindCol (para dados de coluna).

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

  • StrLen_or_Ind é SQL_NTS, SQL_NULL_DATA ou SQL_DEFAULT_PARAM.

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

  • O tipo de dado C é SQL_C_DEFAULT, e o tipo de dado C predefinido para o tipo 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 assume que o tamanho do *DataPtr buffer é o tamanho do tipo de dados C especificado com ValueType ou TargetType e envia o valor total dos dados. Para mais informações, consulte Conversão de Dados de C para Tipos de Dados SQL no Apêndice D: Tipos de Dados.

Devoluções

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR ou SQL_INVALID_HANDLE.

Diagnósticos

Quando o SQLPutData devolve 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 Handle de StatementHandle. A tabela seguinte lista os valores SQLSTATE normalmente devolvidos pelo SQLPutData e explica cada um no contexto desta função; a notação "(DM)" precede as descrições dos SQLSTATEs devolvidas pelo Gestor de Drivers. O código de retorno associado a cada valor SQLSTATE é SQL_ERROR, salvo indicação em contrário.

SQLSTATE Erro Description
01000 Aviso geral Mensagem informativa específica para o condutor. (Função devolve SQL_SUCCESS_WITH_INFO.)
01004 Dados de cadeia, truncados à direita Dados de string ou binários devolvidos para um parâmetro de saída resultavam na truncação de caracteres não em branco ou dados binários não NULL. Se fosse um valor de cadeia, era truncado à direita. (Função devolve SQL_SUCCESS_WITH_INFO.)
07006 Violação de atributo de tipo de dado restrito O valor de dados identificado pelo argumento ValueType em SQLBindParameter para o parâmetro limitado não pôde ser convertido para o tipo de dado identificado pelo argumento ParameterType em SQLBindParameter.
07S01 Uso inválido do parâmetro padrão Um valor de parâmetro, definido com SQLBindParameter, era SQL_DEFAULT_PARAM, e o parâmetro correspondente não tinha valor predefinido.
08S01 Falha da ligação de comunicação A ligação de comunicação entre o driver e a fonte de dados à qual o driver estava ligado falhou antes de a função concluir o processamento.
22001 Dados de cadeia, truncagem à direita A atribuição de um carácter ou valor binário a uma coluna resultava na truncação de caracteres ou bytes não em branco (caracteres) ou não nulos (binários).

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

O SQL_NEED_LONG_DATA_LEN tipo de informação no SQLGetInfo era "Y", e mais dados eram enviados para uma coluna longa (o tipo de dados era SQL_LONGVARCHAR, SQL_LONGVARBINARY ou um tipo longo específico da fonte de dados) do que o especificado no buffer de comprimento correspondente a uma coluna numa 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 ou coluna limitada faziam com que toda a parte (em vez de fracionária) do número fosse truncada quando atribuída à coluna associada à tabela.

Devolver um valor numérico (como numérico ou cadeia) para um ou mais parâmetros de entrada/saída ou saída teria causado truncamento de toda a parte (em vez de fracionária) do número.
22007 Formato de data-hora inválido Os dados enviados para um parâmetro ou coluna vinculados a uma data, hora ou estrutura de carimbo temporal eram, respetivamente, uma data, hora ou carimbo temporal inválido.

Um parâmetro de entrada/saída ou saída era atribuído a uma estrutura C, data, hora ou carimbo temporal, e um valor no parâmetro devolvido era, respetivamente, uma data, hora ou carimbo temporal inválidos. (Função devolve SQL_SUCCESS_WITH_INFO.)
22008 Excesso de campo data-hora Uma expressão de data-hora calculada para um parâmetro de entrada/saída ou saída resultava numa estrutura C de data, hora ou carimbo temporal que era inválida.
22012 Divisão por zero Uma expressão aritmética calculada para um parâmetro de entrada/saída ou saída resultava numa divisão por zero.
22015 Excesso de campo de intervalo Os dados enviados para uma coluna ou parâmetro numérico exato ou de intervalo para um tipo de dado SQL de intervalo causavam uma perda de dígitos significativos.

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

Os dados enviados para colunas ou parâmetros eram atribuídos a um tipo SQL de intervalo, e não havia representação do valor do tipo C no tipo SQL de intervalo.

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

Os dados enviados para colunas ou parâmetros eram atribuídos a uma estrutura C de intervalo, e não havia representação dos dados na estrutura de dados de intervalo.
22018 Valor de personagem inválido para especificação de elenco O tipo C era um tipo numérico exato ou aproximado, uma data-hora ou um tipo de dado de intervalo; o tipo SQL da coluna era um tipo de dado de carácter; e o valor na coluna ou parâmetro não era um literal válido do tipo C limitado.

O tipo SQL era um tipo numérico exato ou aproximado, uma data-hora ou um tipo de dado de intervalo; o tipo C era SQL_C_CHAR; e o valor na coluna ou parâmetro não era um literal válido do tipo SQL limitado.
HY000 Erro geral Ocorreu um erro para o qual não existia um SQLSTATE específico e para o qual não estava definido nenhum SQLSTATE específico da implementação. A mensagem de erro devolvida pelo SQLGetDiagRec no buffer *MessageText descreve o erro e a sua causa.
HY001 Erro de alocação de memória O driver não conseguia alocar a memória necessária para suportar a execução ou conclusão da função.
HY008 Operação cancelada O processamento assíncrono foi ativado para o StatementHandle. A função era chamada e, antes de terminar a execução, o SQLCancel ou SQLCancelHandle era chamado no StatementHandle. Depois, a função era chamada novamente no StatementHandle.

A função era chamada e, antes de terminar a execução, o SQLCancel ou SQLCancelHandle era chamado no StatementHandle a partir de um thread diferente numa aplicação multithread.
HY009 Uso inválido do ponteiro nulo (DM) O argumento DataPtr era um ponto 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 de execução assíncrona era chamada para o handle de ligação associado ao StatementHandle. Esta função assíncrona ainda estava a ser executada quando a função SQLPutData foi chamada.

(DM) SQLExecute, SQLExecDirect ou SQLMoreResults era chamado para o StatementHandle e devolvido SQL_PARAM_DATA_AVAILABLE. Esta função era 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) era chamada para o StatementHandle e continuava a ser executada quando esta função era chamada.
HY013 Erro de gestão de memória A chamada de função não podia ser processada porque os objetos de memória subjacentes não podiam ser acedidos, possivelmente devido a condições de baixa memória.
HY019 Dados não-caracteres e não-binários enviados em pedaços O SQLPutData foi chamado mais do que uma vez para um parâmetro ou coluna, e não estava a ser usado para enviar dados de carácter C para uma coluna com um tipo de dado específico de carácter, binário ou fonte de dados, nem para enviar dados binários C para uma coluna com um tipo de dado específico de carácter, binário ou fonte de dados.
HY020 Tentativa de concatenar um valor nulo SQLPutData foi chamado mais do que uma vez desde a chamada que retornou SQL_NEED_DATA, e numa dessas chamadas, o argumento StrLen_or_Ind continha SQL_NULL_DATA ou SQL_DEFAULT_PARAM.
HY090 Comprimento inválido da corda ou do buffer O argumento DataPtr não era um ponto nulo, e o argumento StrLen_or_Ind era inferior a 0, mas não igual a SQL_NTS ou SQL_NULL_DATA.
HY117 A ligação é suspensa devido ao estado desconhecido da transação. Apenas funções de desconexão e de leitura são permitidas. (DM) Para mais informações sobre o estado suspenso, veja Função SQLEndTran.
HYT01 Expirou o tempo limite de ligação O período de timeout da ligação expirou antes de a fonte de dados responder ao pedido. O período de tempo de expiração da ligação é definido através do SQLSetConnectAttr, SQL_ATTR_CONNECTION_TIMEOUT.
IM001 O driver não suporta esta função (DM) O driver associado ao StatementHandle não suporta a função.
IM017 A sondagem está desativada no modo de notificação assíncrona Sempre que o modelo de notificação é utilizado, o sonding é desativado.
IM018 O SQLCompleteAsync não foi chamado para completar a operação assíncrona anterior neste handle. Se a chamada de função anterior no handle devolver SQL_STILL_EXECUTING e se o modo de notificação estiver ativado, o SQLCompleteAsync deve ser chamado no handle para fazer o pós-processamento e completar a operação.

Se o SQLPutData for chamado ao enviar dados para um parâmetro numa instrução SQL, pode devolver qualquer SQLSTATE que possa ser devolvido pela função chamada para executar a instrução (SQLExecute ou SQLExecDirect). Se for chamada enquanto envia dados para uma coluna que está a ser atualizada ou adicionada com SQLBulkOperations ou atualizada com SQLSetPos, pode devolver qualquer estado SQLSTATE que possa ser devolvido por SQLBulkOperations ou SQLSetPos.

Comments

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

Quando uma aplicação chama SQLParamData para determinar que dados deve enviar, o driver devolve um indicador que a aplicação pode usar para determinar que dados de parâmetros enviar ou onde se encontram os dados das colunas. Também devolve SQL_NEED_DATA, que é um indicador para a aplicação de que deve chamar SQLPutData para enviar os dados. No argumento DataPtr para SQLPutData, a aplicação passa um ponteiro para o buffer que contém os dados reais do parâmetro ou coluna.

Quando o driver retorna SQL_SUCCESS para SQLPutData, a aplicação chama novamente SQLParamData . O SQLParamData devolve SQL_NEED_DATA se for necessário enviar mais dados, caso em que a aplicação chama novamente o SQLPutData . Devolve SQL_SUCCESS se todos os dados de execução já foram enviados. A aplicação chama então novamente SQLParamData . Se o driver devolver SQL_NEED_DATA e outro indicador em *ValuePtrPtr, requer dados para outro parâmetro ou coluna e o SQLPutData é chamado novamente. Se o driver devolver SQL_SUCCESS, então todos os dados de execução foram enviados e a instrução SQL pode ser executada ou a chamada SQLBulkOperations ou SQLSetPos pode ser processada.

Para mais informações sobre como os dados do parâmetro de execução são passados no momento da execução da instrução, veja "Passing Parameter Values" em SQLBindParameter e Sending Long Data. Para mais informações sobre como os dados da coluna na execução são atualizados ou adicionados, consulte a secção "Usar SQLSetPos" no SQLSetPos, "Realizar Atualizações em Massa Usando Favoritos" no SQLBulkOperations, e Longo Dados, SQLSetPos e SQLBulkOperations.

Note

Uma aplicação pode usar o SQLPutData para enviar dados em partes apenas quando envia dados de carácter C para uma coluna com um tipo de dado específico de carácter, binário ou fonte de dados, ou ao enviar dados binários C para uma coluna com um tipo de dado específico de carácter, binário ou fonte de dados. Se o SQLPutData for chamado mais do que uma vez em quaisquer outras condições, devolve SQL_ERROR e SQLSTATE HY019 (dados não caracteres e não binários enviados em partes).

Example

O exemplo seguinte assume um nome de fonte de dados chamado Test. A base de dados associada deve ter uma tabela que pode criar, da seguinte forma:

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 Veja
Ligar um buffer a um parâmetro Função SQLBindParameter
Cancelamento do processamento de extratos Função SQLCancel
Execução de uma instrução SQL Função SQLExecDirect
Execução de uma instrução SQL preparada Função SQLExecute
Devolver o próximo parâmetro para enviar dados para Função SQLParamData