Função SQLPutData
Compatibilidade
Versão introduzida: ODBC 1.0 Conformidade com os padrões: 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 fonte de dados (por exemplo, parâmetros dos tipos SQL_LONGVARBINARY ou 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
Identificador de declaração
[Entrada] Identificador de instrução.
DataPtr
[Entrada] Ponteiro para um buffer que contém os dados reais do 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 pressupõe 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 em 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 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 Handle de StatementHandle. A tabela a seguir lista os valores SQLSTATE comumente 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 de outra forma.
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 | Os dados binários ou de cadeia de caracteres 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 string, era 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 estava conectado falhou antes que a função concluísse 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 vazios (caracteres) ou não nulos (binários). O tipo de informação SQL_NEED_LONG_DATA_LEN em SQLGetInfo era "Y" e mais dados foram enviados para um parâmetro long (o tipo de dados era SQL_LONGVARCHAR, SQL_LONGVARBINARY ou um tipo de dados específico da fonte de dados long) do que o especificado com o argumento StrLen_or_IndPtr em SQLBindParameter. O tipo de informação SQL_NEED_LONG_DATA_LEN em SQLGetInfo era "Y" e mais dados foram enviados para uma coluna longa (o tipo de dados era SQL_LONGVARCHAR, SQL_LONGVARBINARY ou um tipo de dados específico da fonte de dados longa) do que o 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 ou coluna vinculada fizeram com que toda a parte (em oposição à 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 oposição à fracionária) do número fosse truncada. |
22007 | Formato de data e hora inválido | Os dados enviados para um parâmetro ou coluna que estava associado a uma estrutura de data, hora ou carimbo de data/hora eram, respectivamente, uma data, hora ou carimbo de data/hora inválidos. 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 foi, respectivamente, uma data, hora ou carimbo de data/hora inválido. (A função retorna SQL_SUCCESS_WITH_INFO.) |
22008 | Estouro de campo de data e hora | Uma expressão datetime calculada 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 na divisão por zero. |
22015 | Estouro de campo de intervalo | Os dados enviados para uma coluna ou parâmetro numérico ou de 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 tiveram 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 de intervalo. Os dados enviados para uma coluna ou parâmetro numérico exato ou de intervalo C para um tipo de intervalo C 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 de intervalo. |
22018 | Valor de caractere inválido para especificação de conversão | O tipo C era um tipo de dados numérico exato ou aproximado, uma data/hora 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 tipo de dados numérico exato ou aproximado, uma data e hora 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 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 o 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ção | (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 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 o StatementHandle e retornado SQL_PARAM_DATA_AVAILABLE. Essa função foi chamada antes que os dados fossem recuperados para todos os parâmetros transmitidos. (DM) Uma função de execução assíncrona (não esta) foi chamada para o 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 relacionados a 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 de caractere, binário ou específico da fonte de dados ou para enviar dados binários C para uma coluna com um tipo de dados de caractere, binário ou específico da fonte de dados. |
HY020 | Tentativa de concatenar um valor nulo | SQLPutData foi chamado mais de uma vez desde 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 | Cadeia de caracteres ou comprimento de buffer 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 desconhecido da transação. Somente funções de desconexão 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 que a fonte de dados respondesse à 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 suporta esta 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 durante o envio de 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 ele for chamado durante o envio de dados para uma coluna que está sendo atualizada ou adicionada com SQLBulkOperations ou sendo atualizada com SQLSetPos, ele poderá retornar qualquer SQLSTATE que possa ser retornado por SQLBulkOperations ou SQLSetPos.
Comentários
SQLPutData pode ser chamado para fornecer 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 ele deve enviar, o driver retorna um indicador que o aplicativo pode usar para determinar quais dados de parâmetro enviar ou 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 do parâmetro ou coluna.
Quando o driver retorna SQL_SUCCESS para SQLPutData, o aplicativo chama SQLParamData novamente. SQLParamData retorna SQL_NEED_DATA se mais dados precisam ser enviados, caso em que o aplicativo chama SQLPutData novamente. Ele retorna 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 de dados em execução foram 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 momento da 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 de caractere, binário ou específico da fonte de dados ou ao enviar dados binários C para uma coluna com um tipo de dados de caractere, binário ou específico da fonte de dados. 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 de caracteres enviados em partes).
Exemplo
O exemplo a seguir pressupõe um nome de fonte de dados chamado Test. O banco de dados associado deve ter uma tabela que você possa 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);
}
Funções relacionadas
Para obter informações sobre | Consulte |
---|---|
Associando um buffer a um parâmetro | Função SQLBindParameter |
Cancelando o processamento de instruções | 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 |