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);
}
Funções relacionadas
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 |