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 caractères ou de données 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 Unicode C, 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 à chaque appel pour un paramètre ou une colonne donné. StrLen_or_Ind est ignoré, sauf s’il remplit 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 correspond à 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 de SQLSTATEs retournées par le Gestionnaire de pilotes. Le code de retour associé à chaque valeur SQLSTATE est SQL_ERROR, sauf indication contraire.

SQLSTATE Error 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 chaîne ou binaires retournées pour un paramètre de sortie ont entraîné la troncation de caractères non vides ou de données binaires 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 restreinte 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 de la liaison de communication La liaison de communication entre le pilote et la source de données à laquelle le pilote a été connecté a échoué avant que la fonction n’ait terminé le traitement.
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 ou d’octets non vides (caractère) ou non null (binaire).

Le type d’informations SQL_NEED_LONG_DATA_LEN dans SQLGetInfo était « Y », et plus de 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 celles spécifiées avec l’argument StrLen_or_IndPtr dans SQLBindParameter.

Le type d’informations SQL_NEED_LONG_DATA_LEN dans SQLGetInfo était « Y », et plus de données ont été envoyées pour une colonne longue (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 spécifiées dans la mémoire tampon de longueur correspondant à une colonne dans une ligne de données ajoutées ou mises à jour avec SQLBulkOperations ou mises à jour avec SQLSetPos.
22003 Valeur numérique hors plage Les données envoyées pour une colonne ou un paramètre numérique lié ont entraîné la tronquation de la partie entière (et non fractionnaire) du nombre lorsqu’elle est affectée à la colonne de table associée.

Le renvoi d’une valeur numérique (sous forme numérique ou chaîne) pour un ou plusieurs paramètres d’entrée/sortie ou de sortie aurait entraîné la tronquation de la partie entière (et non fractionnaire) 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 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é une 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 entraîné 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ériques 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 il n’y avait aucune représentation de la valeur du type C dans le 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 d’intervalle C ont entraîné 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 d’intervalle C et il n’y avait aucune représentation des données 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 de données 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 de données 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 pas de SQLSTATE spécifique et pour laquelle 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 la 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 l’instruction StatementHandle. La fonction a été appelée et, avant de terminer l’exécution, SQLCancel ou SQLCancelHandle a été appelé sur l’InstructionHandle. Ensuite, la fonction a été appelée à nouveau sur l’InstructionHandle.

La fonction a été appelée et, avant de terminer l’exécution, SQLCancel ou SQLCancelHandle a été appelé 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 d’exécution asynchrone a été appelée pour le handle de connexion associé à l’InstructionHandle. 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 a 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.

(DM) Une fonction d’exécution asynchrone (et non celle-ci) a été appelée pour l’InstructionHandle et s’exécutait toujours 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 consultés, peut-être en raison de conditions de mémoire insuffisantes.
HY019 Données non-caractères 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 de caractère C à 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 caractère, un binaire ou un type de données spécifique à la source de données.
HY020 Tentative de concaténer une valeur null SQLPutData a été appelé plusieurs fois depuis l’appel qui a renvoyé SQL_NEED_DATA, et dans l’un de ces appels, l’argument StrLen_or_Ind contenait SQL_NULL_DATA ou SQL_DEFAULT_PARAM.
HY090 Chaîne ou longueur de 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 n’était 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 FONCTION SQLEndTran.
HYT01 Délai d’attente de la connexion expiré Le délai d’expiration de la connexion a expiré avant que la source de données réponde à la demande. La période de délai d’expiration de la connexion est définie via SQLSetConnectAttr, SQL_ATTR_CONNECTION_TIMEOUT.
IM001 Le pilote ne prend pas en charge cette fonction (DM) Le pilote associé à l’InstructionHandle 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 effectuer 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). S’il est appelé lors de l’envoi de données pour une colonne en cours de mise à jour ou d’ajout avec SQLBulkOperations ou mise à jour avec SQLSetPos, il peut retourner n’importe quel SQLSTATE qui peut être retourné par SQLBulkOperations ou SQLSetPos.

Commentaires

SQLPutData peut être appelé pour fournir des données à 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ù les données de colonne peuvent être trouvées. Il retourne également SQL_NEED_DATA, qui indique à l’application qu’elle doit appeler SQLPutData pour envoyer les données. Dans l’argument DataPtr vers 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 d’autres données doivent être envoyées, auquel cas l’application appelle à nouveau SQLPutData . Il retourne SQL_SUCCESS si toutes les données à l’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 au moment de 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 de données à l’exécution sont transmises 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 de données à l’exécution sont mises à jour ou ajoutées, consultez la section « Utilisation de SQLSetPos » dans SQLSetPos, « Exécution de Mises à jour utilisation de signets » dans SQLBulkOperations et Données longues et SQLSetPos et SQLBulkOperations.

Notes

Une application peut utiliser SQLPutData pour envoyer des données en parties uniquement lors de l’envoi de données de caractère C à une colonne avec un type de données spécifique à une source de données, ou lors de l’envoi de données binaires C à une colonne avec un caractère, un binaire ou un type de données spécifique à la source de données. Si SQLPutData est appelé plusieurs fois dans d’autres conditions, il retourne SQL_ERROR et SQLSTATE HY019 (données non-caractères 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 obtenir des informations sur Consultez
Liaison d’une mémoire tampon à un paramètre Fonction SQLBindParameter
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