Partager via


Fonction SQLPutData

Conformité
Version introduite : Conformité aux normes ODBC 1.0 : ISO 92

Résumé
SQLPutData permet à une application d’envoyer des données pour un paramètre ou une colonne au pilote au moment de l’exécution de l’instruction. Cette fonction peut être utilisée pour envoyer des valeurs de données de caractères ou binaires en parties à une colonne avec un type de données spécifique à une source de données (par exemple, les paramètres des types SQL_LONGVARBINARY ou SQL_LONGVARCHAR). SQLPutData prend en charge la liaison à un type de données C Unicode, même si le pilote sous-jacent ne prend pas en charge les données Unicode.

Syntaxe

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

Arguments

StatementHandle
[Entrée] Handle d’instruction.

DataPtr
[Entrée] Pointeur vers une mémoire tampon contenant les données réelles du paramètre ou de la colonne. Les données doivent se trouver dans le type de données C spécifié dans l’argument ValueType de SQLBindParameter (pour les données de paramètre) ou l’argument TargetType de SQLBindCol (pour les données de colonne).

StrLen_or_Ind
[Entrée] Longueur de *DataPtr. Spécifie la quantité de données envoyées dans un appel à SQLPutData. La quantité de données peut varier avec chaque appel pour un paramètre ou une colonne donné. StrLen_or_Ind est ignorée, sauf si elle répond à l’une des conditions suivantes :

  • StrLen_or_Ind est SQL_NTS, SQL_NULL_DATA ou SQL_DEFAULT_PARAM.

  • Le type de données C spécifié dans SQLBindParameter ou SQLBindCol est SQL_C_CHAR ou SQL_C_BINARY.

  • Le type de données C est SQL_C_DEFAULT, et le type de données C par défaut pour le type de données SQL spécifié est SQL_C_CHAR ou SQL_C_BINARY.

Pour tous les autres types de données C, si StrLen_or_Ind n’est pas SQL_NULL_DATA ou SQL_DEFAULT_PARAM, le pilote suppose que la taille de la mémoire tampon *DataPtr est la taille du type de données C spécifié avec ValueType ou TargetType et envoie la valeur de données entière. Pour plus d’informations, consultez Conversion de données de C en types de données SQL dans l’annexe D : Types de données.

Retours

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR ou SQL_INVALID_HANDLE.

Diagnostics

Lorsque SQLPutData retourne SQL_ERROR ou SQL_SUCCESS_WITH_INFO, une valeur SQLSTATE associée peut être obtenue en appelant SQLGetDiagRec avec un HandleType de SQL_HANDLE_STMT et un Handle of StatementHandle. Le tableau suivant répertorie les valeurs SQLSTATE couramment retournées par SQLPutData et explique chacune d’elles dans le contexte de cette fonction ; la notation « (DM) » précède les descriptions des SQLSTATEs retournées par le Gestionnaire de pilotes. Le code de retour associé à chaque valeur SQLSTATE est SQL_ERROR, sauf indication contraire.

SQLSTATE Erreur Description
01000 Avertissement général Message d’information spécifique au pilote. (La fonction retourne SQL_SUCCESS_WITH_INFO.)
01004 Données de chaîne, tronquées à droite Les données de type chaîne ou binaire retournées pour un paramètre de sortie ont entraîné la troncation des données binaires non vides ou non NULL. S’il s’agissait d’une valeur de chaîne, elle était tronquée à droite. (La fonction retourne SQL_SUCCESS_WITH_INFO.)
07006 Violation d’attribut de type de données restreint La valeur de données identifiée par l’argument ValueType dans SQLBindParameter pour le paramètre lié n’a pas pu être convertie en type de données identifié par l’argument ParameterType dans SQLBindParameter.
07S01 Utilisation non valide du paramètre par défaut Une valeur de paramètre, définie avec SQLBindParameter, était SQL_DEFAULT_PARAM et le paramètre correspondant n’avait pas de valeur par défaut.
08S01 Échec du lien de communication Le lien de communication entre le pilote et la source de données à laquelle le pilote a été connecté a échoué avant l’achèvement du traitement de la fonction.
22001 Données de chaîne, troncation droite L’affectation d’un caractère ou d’une valeur binaire à une colonne a entraîné la troncation de caractères non vides (caractères) ou de caractères non null (binaires) ou d’octets.

Le type d’informations SQL_NEED_LONG_DATA_LEN dans SQLGetInfo était « Y », et d’autres données ont été envoyées pour un paramètre long (le type de données était SQL_LONGVARCHAR, SQL_LONGVARBINARY ou un type de données spécifique à une source de données longue) que celui spécifié avec l’argument StrLen_or_IndPtr dans SQLBindParameter.

Le type d’informations SQL_NEED_LONG_DATA_LEN dans SQLGetInfo était « Y », et d’autres données ont été envoyées pour une longue colonne (le type de données était SQL_LONGVARCHAR, SQL_LONGVARBINARY ou un type de données spécifique à une source de données longue) que celui spécifié dans la mémoire tampon de longueur correspondant à une colonne d’une ligne de données ajoutées ou mises à jour avec SQLBulkOperations ou mis à jour avec SQLSetPos.
22003 Valeur numérique hors plage Les données envoyées pour un paramètre numérique lié ou une colonne ont provoqué la troncation de la partie entière (par opposition à la fraction) du nombre lorsqu’elle est affectée à la colonne de table associée.

Le renvoi d’une valeur numérique (en tant que numérique ou chaîne) pour un ou plusieurs paramètres d’entrée/sortie ou de sortie aurait provoqué la troncation de l’ensemble (par opposition à la fraction) du nombre.
22007 Format datetime non valide Les données envoyées pour un paramètre ou une colonne lié à une structure de date, d’heure ou d’horodatage étaient, respectivement, une date, une heure ou un horodatage non valides.

Un paramètre d’entrée/sortie ou de sortie était lié à une structure C de date, d’heure ou d’horodatage, et une valeur dans le paramètre retourné était, respectivement, une date, une heure ou un horodatage non valide. (La fonction retourne SQL_SUCCESS_WITH_INFO.)
22008 Dépassement de champ Datetime Une expression datetime calculée pour un paramètre d’entrée/sortie ou de sortie a entraîné une structure C de date, d’heure ou d’horodatage C non valide.
22012 Division par zéro Une expression arithmétique calculée pour un paramètre d’entrée/sortie ou de sortie a entraîné la division par zéro.
22015 Dépassement de champ d’intervalle Les données envoyées pour une colonne ou un paramètre numérique ou d’intervalle exact à un type de données SQL d’intervalle ont provoqué une perte de chiffres significatifs.

Les données ont été envoyées pour une colonne ou un paramètre d’intervalle avec plusieurs champs, ont été converties en type de données numérique et n’avaient aucune représentation dans le type de données numérique.

Les données envoyées pour les données de colonne ou de paramètre ont été affectées à un type SQL d’intervalle, et aucune représentation de la valeur du type C n’a été affectée au type SQL d’intervalle.

Les données envoyées pour une colonne ou un paramètre C numérique ou d’intervalle exact à un type C d’intervalle ont provoqué une perte de chiffres significatifs.

Les données envoyées pour les données de colonne ou de paramètre ont été affectées à une structure C d’intervalle et aucune représentation des données n’a été représentée dans la structure de données d’intervalle.
22018 Valeur de caractère non valide pour la spécification de cast Le type C était un type numérique exact ou approximatif, un datetime ou un type de données d’intervalle ; le type SQL de la colonne était un type de données caractère ; et la valeur de la colonne ou du paramètre n’était pas un littéral valide du type C lié.

Le type SQL était un type numérique exact ou approximatif, un datetime ou un type de données d’intervalle ; le type C était SQL_C_CHAR ; et la valeur de la colonne ou du paramètre n’était pas un littéral valide du type SQL lié.
HY000 Erreur générale Une erreur s’est produite pour laquelle il n’y avait aucun SQLSTATE spécifique et pour lequel aucun SQLSTATE spécifique à l’implémentation n’a été défini. Le message d’erreur retourné par SQLGetDiagRec dans la mémoire tampon *MessageText décrit l’erreur et sa cause.
HY001 Erreur d’allocation de mémoire Le pilote n’a pas pu allouer de mémoire nécessaire pour prendre en charge l’exécution ou l’achèvement de la fonction.
HY008 Opération annulée Le traitement asynchrone a été activé pour StatementHandle. La fonction a été appelée et avant l’exécution terminée, SQLCancel ou SQLCancelHandle a été appelée sur StatementHandle. Ensuite, la fonction a été appelée à nouveau sur l’instructionHandle.

La fonction a été appelée et avant qu’elle ait terminé l’exécution, SQLCancel ou SQLCancelHandle a été appelée sur l’InstructionHandle à partir d’un autre thread dans une application multithread.
HY009 Utilisation non valide du pointeur Null (DM) L’argument DataPtr était un pointeur Null et l’argument StrLen_or_Ind n’était pas 0, SQL_DEFAULT_PARAM ou SQL_NULL_DATA.
HY010 Erreur de séquence de fonction (DM) L’appel de fonction précédent n’était pas un appel à SQLPutData ou SQLParamData.

(DM) Une fonction en cours d’exécution asynchrone a été appelée pour le handle de connexion associé à StatementHandle. Cette fonction asynchrone était toujours en cours d’exécution lorsque la fonction SQLPutData a été appelée.

(DM) SQLExecute, SQLExecDirect ou SQLMoreResults a été appelé pour l’instruction StatementHandle et retourné SQL_PARAM_DATA_AVAILABLE. Cette fonction a été appelée avant la récupération des données pour tous les paramètres diffusés en continu.

(DM) Une fonction en cours d’exécution asynchrone (et non celle-ci) a été appelée pour l’instruction StatementHandle et était toujours en cours d’exécution lorsque cette fonction a été appelée.
HY013 Erreur de gestion de la mémoire L’appel de fonction n’a pas pu être traité, car les objets de mémoire sous-jacents n’ont pas pu être accessibles, éventuellement en raison de conditions de mémoire insuffisantes.
HY019 Données non binaires et non binaires envoyées en morceaux SQLPutData a été appelé plusieurs fois pour un paramètre ou une colonne, et il n’était pas utilisé pour envoyer des données C de caractère à une colonne avec un type de données spécifique à une source de données, ou pour envoyer des données C binaires à une colonne avec un type de données spécifique à une source de données, un caractère, un binaire ou une source de données.
HY020 Tentative de concaténation d’une valeur Null SQLPutData a été appelé plusieurs fois depuis l’appel qui a retourné SQL_NEED_DATA, et dans l’un de ces appels, l’argument StrLen_or_Ind contenait SQL_NULL_DATA ou SQL_DEFAULT_PARAM.
HY090 Longueur de la chaîne ou de la mémoire tampon non valide L’argument DataPtr n’était pas un pointeur Null et l’argument StrLen_or_Ind était inférieur à 0, mais pas égal à SQL_NTS ou SQL_NULL_DATA.
HY117 La connexion est suspendue en raison d’un état de transaction inconnu. Seules les fonctions de déconnexion et de lecture seule sont autorisées. (DM) Pour plus d’informations sur l’état suspendu, consultez la fonction SQLEndTran.
HYT01 Délai d’attente de la connexion expiré La période d’expiration de la connexion a expiré avant que la source de données ne réponde à la demande. La période d’expiration de connexion est définie via SQLSetConnectAttr, SQL_ATTR_CONNECTION_TIMEOUT.
IM001 Le pilote ne prend pas en charge cette fonction (DM) Le pilote associé à StatementHandle ne prend pas en charge la fonction.
IM017 L’interrogation est désactivée en mode de notification asynchrone Chaque fois que le modèle de notification est utilisé, l’interrogation est désactivée.
IM018 SQLCompleteAsync n’a pas été appelé pour terminer l’opération asynchrone précédente sur ce handle. Si l’appel de fonction précédent sur le handle retourne SQL_STILL_EXECUTING et si le mode de notification est activé, SQLCompleteAsync doit être appelé sur le handle pour effectuer un post-traitement et terminer l’opération.

Si SQLPutData est appelé lors de l’envoi de données pour un paramètre dans une instruction SQL, il peut retourner n’importe quel SQLSTATE qui peut être retourné par la fonction appelée pour exécuter l’instruction (SQLExecute ou SQLExecDirect). Si elle est appelée lors de l’envoi de données pour une colonne mise à jour ou ajoutée avec SQLBulkOperations ou mise à jour avec SQLSetPos, elle peut retourner n’importe quel SQLSTATE qui peut être retourné par SQLBulkOperations ou SQLSetPos.

Commentaires

SQLPutData peut être appelé pour fournir des données au moment de l’exécution pour deux utilisations : les données de paramètre à utiliser dans un appel à SQLExecute ou SQLExecDirect, ou les données de colonne à utiliser lorsqu’une ligne est mise à jour ou ajoutée par un appel à SQLBulkOperations ou est mise à jour par un appel à SQLSetPos.

Lorsqu’une application appelle SQLParamData pour déterminer les données qu’elle doit envoyer, le pilote retourne un indicateur que l’application peut utiliser pour déterminer les données de paramètre à envoyer ou où trouver les données de colonne. Elle retourne également SQL_NEED_DATA, qui est un indicateur à l’application qu’elle doit appeler SQLPutData pour envoyer les données. Dans l’argument DataPtr de SQLPutData, l’application transmet un pointeur vers la mémoire tampon contenant les données réelles du paramètre ou de la colonne.

Lorsque le pilote retourne SQL_SUCCESS pour SQLPutData, l’application appelle à nouveau SQLParamData. SQLParamData retourne SQL_NEED_DATA si davantage de données doivent être envoyées, auquel cas l’application appelle à nouveau SQLPutData . Elle retourne SQL_SUCCESS si toutes les données en cours d’exécution ont été envoyées. L’application appelle ensuite à nouveau SQLParamData . Si le pilote retourne SQL_NEED_DATA et un autre indicateur dans *ValuePtrPtr, il nécessite des données pour un autre paramètre ou colonne et SQLPutData est appelé à nouveau. Si le pilote retourne SQL_SUCCESS, toutes les données à l’exécution ont été envoyées et l’instruction SQL peut être exécutée ou l’appel SQLBulkOperations ou SQLSetPos peut être traité.

Pour plus d’informations sur la façon dont les données des paramètres d’exécution au moment de l’exécution des données sont passées au moment de l’exécution de l’instruction, consultez « Passage de valeurs de paramètre » dans SQLBindParameter et envoi de données longues. Pour plus d’informations sur la façon dont les données de colonne d’exécution sont mises à jour ou ajoutées, consultez la section « Utilisation de SQLSetPos » dans SQLSetPos, « Exécution de mises à jour en bloc à l’aide de signets » dans SQLBulkOperations et SqlSetPos et SQLBulkOperations.

Remarque

Une application peut utiliser SQLPutData pour envoyer des données en parties uniquement lors de l’envoi de données C de caractère à une colonne avec un type de données spécifique à une source de données ou un type de données spécifique à une source de données ou lors de l’envoi de données C binaires à une colonne avec un type de données spécifique à une source de données ou un caractère. Si SQLPutData est appelé plusieurs fois dans d’autres conditions, il retourne SQL_ERROR et SQLSTATE HY019 (données non binaires et non binaires envoyées en morceaux).

Exemple

L’exemple suivant suppose un nom de source de données appelé Test. La base de données associée doit avoir une table que vous pouvez créer, comme suit :

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);  
}  
Pour plus d’informations sur Consultez
Liaison d’une mémoire tampon à un paramètre SQLBindParameter, fonction
Annulation du traitement des instructions SQLCancel, fonction
Exécution d’une instruction SQL SQLExecDirect, fonction
Exécution d’une instruction SQL préparée SQLExecute, fonction
Retour du paramètre suivant pour lequel envoyer des données SQLParamData, fonction

Voir aussi

Informations de référence sur l’API ODBC
Fichiers d’en-tête ODBC