Partager via


Fonction SQLGetData

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

Résumé
SQLGetData récupère des données pour une seule colonne dans le jeu de résultats ou pour un paramètre unique après que SQLParamData a retourné SQL_PARAM_DATA_AVAILABLE. Il peut être appelé plusieurs fois pour récupérer des données de longueur variable en parties.

Syntaxe

  
SQLRETURN SQLGetData(  
      SQLHSTMT       StatementHandle,  
      SQLUSMALLINT   Col_or_Param_Num,  
      SQLSMALLINT    TargetType,  
      SQLPOINTER     TargetValuePtr,  
      SQLLEN         BufferLength,  
      SQLLEN *       StrLen_or_IndPtr);  

Arguments

StatementHandle
[Entrée] Handle d’instruction.

Col_or_Param_Num
[Entrée] Pour récupérer des données de colonne, il s’agit du numéro de la colonne pour laquelle retourner des données. Les colonnes du jeu de résultats sont numérotées dans l’ordre croissant des colonnes à partir de 1. La colonne signet est le numéro de colonne 0 ; cela peut être spécifié uniquement si les signets sont activés.

Pour récupérer des données de paramètre, il s’agit de l’ordinal du paramètre, qui commence à 1.

TargetType
[Entrée] Identificateur de type du type de données C de la mémoire tampon *TargetValuePtr . Pour obtenir la liste des types de données C et des identificateurs de type valides, consultez la section Types de données C dans l’Annexe D : Types de données.

Si TargetType est SQL_ARD_TYPE, le pilote utilise l’identificateur de type spécifié dans le champ SQL_DESC_CONCISE_TYPE de l’ARD. Si TargetType est SQL_APD_TYPE, SQLGetData utilise le même type de données C que celui spécifié dans SQLBindParameter. Sinon, le type de données C spécifié dans SQLGetData remplace le type de données C spécifié dans SQLBindParameter. S’il est SQL_C_DEFAULT, le pilote sélectionne le type de données C par défaut en fonction du type de données SQL de la source.

Vous pouvez également spécifier un type de données C étendu. Pour plus d’informations, consultez Types de données C dans ODBC.

TargetValuePtr
[Sortie] Pointeur vers la mémoire tampon dans laquelle retourner les données.

TargetValuePtr ne peut pas être NULL.

BufferLength
[Entrée] Longueur de la mémoire tampon *TargetValuePtr en octets.

Le pilote utilise BufferLength pour éviter d’écrire au-delà de la fin de la mémoire tampon *TargetValuePtr lors du retour de données de longueur variable, telles que des données caractère ou binaires. Notez que le pilote compte le caractère d’arrêt Null lors du renvoi de données de caractères à *TargetValuePtr. *TargetValuePtr doit donc contenir de l’espace pour le caractère d’arrêt Null, sinon le pilote tronque les données.

Lorsque le pilote retourne des données de longueur fixe, telles qu’un entier ou une structure de date, le pilote ignore BufferLength et suppose que la mémoire tampon est suffisamment grande pour contenir les données. Il est donc important que l’application alloue une mémoire tampon suffisamment grande pour les données de longueur fixe, sinon le pilote écrit au-delà de la fin de la mémoire tampon.

SQLGetData retourne SQLSTATE HY090 (chaîne ou longueur de mémoire tampon non valide) lorsque BufferLength est inférieur à 0, mais pas lorsque BufferLength a la valeur 0.

StrLen_or_IndPtr
[Sortie] Pointeur vers la mémoire tampon dans laquelle retourner la longueur ou la valeur de l’indicateur. S’il s’agit d’un pointeur Null, aucune longueur ou valeur d’indicateur n’est retournée. Cette opération renvoie une erreur lorsque les données extraites ont la valeur NULL.

SQLGetData peut retourner les valeurs suivantes dans la mémoire tampon longueur/indicateur :

  • Longueur des données disponibles à retourner

  • SQL_NO_TOTAL

  • SQL_NULL_DATA

Pour plus d’informations, consultez Utilisation de valeurs de longueur/d’indicateur et « Commentaires » dans cette rubrique.

Retours

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_STILL_EXECUTING, SQL_ERROR ou SQL_INVALID_HANDLE.

Diagnostics

Lorsque SQLGetData 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 de StatementHandle. Le tableau suivant répertorie les valeurs SQLSTATE couramment retournées par SQLGetData 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 Toutes les données de la colonne spécifiée , Col_or_Param_Num, n’ont pas pu être récupérées en un seul appel à la fonction. SQL_NO_TOTAL ou la longueur des données restantes dans la colonne spécifiée avant l’appel actuel à SQLGetData est retournée dans *StrLen_or_IndPtr. (La fonction retourne SQL_SUCCESS_WITH_INFO.)

Pour plus d’informations sur l’utilisation de plusieurs appels à SQLGetData pour une seule colonne, consultez « Commentaires ».
01S07 Troncation fractionnaire Les données retournées pour une ou plusieurs colonnes ont été tronquées. Pour les types de données numériques, la partie fractionnaire du nombre a été tronquée. Pour les types de données time, timestamp et interval contenant un composant de temps, la partie fractionnaire de l’heure a été tronquée.

(La fonction retourne SQL_SUCCESS_WITH_INFO.)
07006 Violation d’attribut de type de données restreint La valeur de données d’une colonne dans le jeu de résultats ne peut pas être convertie en type de données C spécifié par l’argument TargetType.
07009 Index de descripteur non valide La valeur spécifiée pour l’argument Col_or_Param_Num était 0 et l’attribut d’instruction SQL_ATTR_USE_BOOKMARKS a été défini sur SQL_UB_OFF.

La valeur spécifiée pour l’argument Col_or_Param_Num était supérieure au nombre de colonnes dans le jeu de résultats.

La valeur Col_or_Param_Num n’était pas égale à l’ordinal du paramètre disponible.

(DM) La colonne spécifiée a été liée. Cette description ne s’applique pas aux pilotes qui retournent le masque de bits SQL_GD_BOUND pour l’option SQL_GETDATA_EXTENSIONS dans SQLGetInfo.

(DM) Le nombre de la colonne spécifiée était inférieur ou égal au nombre de la colonne liée la plus élevée. Cette description ne s’applique pas aux pilotes qui retournent le masque de bits SQL_GD_ANY_COLUMN pour l’option SQL_GETDATA_EXTENSIONS dans SQLGetInfo.

(DM) L’application a déjà appelé SQLGetData pour la ligne actuelle ; le numéro de la colonne spécifiée dans l’appel actuel était inférieur au nombre de la colonne spécifiée dans l’appel précédent ; et le pilote ne retourne pas le masque de bits SQL_GD_ANY_ORDER pour l’option SQL_GETDATA_EXTENSIONS dans SQLGetInfo.

(DM) L’argument TargetType a été SQL_ARD_TYPE, et l’enregistrement de descripteur Col_or_Param_Num dans l’ARD a échoué la vérification de cohérence.

(DM) L’argument TargetType a été SQL_ARD_TYPE, et la valeur dans le champ SQL_DESC_COUNT de l’argument ARD était inférieure à l’argument Col_or_Param_Num .
08S01 Échec de la liaison de communication Le lien de communication entre le pilote et la source de données à laquelle le pilote a été connecté a échoué avant la fin du traitement de la fonction.
22002 Variable d’indicateur requise mais non fournie StrLen_or_IndPtr était un pointeur Null et les données NULL ont été récupérées.
22003 Valeur numérique hors plage Le renvoi de la valeur numérique (sous forme numérique ou chaîne) pour la colonne aurait entraîné la tronquation de la partie entière (par opposition à la fraction) du nombre.

Pour plus d’informations, consultez Annexe D : Types de données.
22007 Format datetime non valide La colonne de caractères dans le jeu de résultats était liée à une structure de date, d’heure ou d’horodatage C, et la valeur dans la colonne était une date, une heure ou un horodatage non valides, respectivement. Pour plus d’informations, consultez Annexe D : Types de données.
22012 Division par zéro Une valeur d’une expression arithmétique qui a entraîné une division par zéro a été retournée.
22015 Dépassement de champ d’intervalle L’affectation d’un type SQL numérique ou d’intervalle exact à un type C d’intervalle a entraîné une perte de chiffres significatifs dans le champ de début.

Lors du retour de données à un type interval C, il n’y avait aucune représentation de la valeur du type SQL dans le type interval C.
22018 Valeur de caractère non valide pour la spécification de cast Une colonne de caractères dans le jeu de résultats a été retournée à une mémoire tampon de caractère C, et la colonne contenait un caractère pour lequel il n’y avait aucune représentation dans le jeu de caractères de la mémoire tampon.

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 n’était pas un littéral valide du type C lié.
24 000 État de curseur non valide (DM) La fonction a été appelée sans appeler d’abord SQLFetch ou SQLFetchScroll pour positionner le curseur sur la ligne de données requise.

(DM) L’InstructionHandle était dans un état exécuté, mais aucun jeu de résultats n’a été associé à l’InstructionHandle.

Un curseur était ouvert sur l’InstructionHandle et SQLFetchou SQLFetchScroll avait été appelé, mais le curseur a été positionné avant le début du jeu de résultats ou après la fin du jeu de résultats.
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.
HY003 Type de programme hors limites (DM) L’argument TargetType n’était pas un type de données valide, SQL_C_DEFAULT, SQL_ARD_TYPE (en cas de récupération de données de colonne) ou SQL_APD_TYPE (en cas de récupération de données de paramètre).

(DM) L’argument Col_or_Param_Num était 0, et l’argument TargetType n’était pas SQL_C_BOOKMARK pour un signet de longueur fixe ou SQL_C_VARBOOKMARK pour un signet de longueur variable.
HY008 Opération annulée Le traitement asynchrone a été activé pour l’InstructionHandle. La fonction a été appelée et, avant la fin de son exécution, SQLCancel ou SQLCancelHandle a été appelée sur l’InstructionHandle, puis la fonction a été appelée à nouveau sur l’InstructionHandle.

La fonction a été appelée et, avant la fin de son exécution, SQLCancel ou SQLCancelHandle a été appelée sur l’InstructionHandle à partir d’un thread différent dans une application multithread, puis la fonction a été appelée à nouveau sur l’InstructionHandle.
HY009 Utilisation non valide du pointeur Null (DM) L’argument TargetValuePtr était un pointeur null.
HY010 Erreur de séquence de fonction (DM) L’InstructionHandle spécifiée n’était pas dans un état exécuté. La fonction a été appelée sans avoir d’abord appelé SQLExecDirect, SQLExecute ou une fonction de catalogue.

(DM) Une fonction en 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 SQLGetData a été appelée.

(DM) Une fonction en cours d’exécution asynchrone (et non celle-ci) a été appelée pour l’InstructionHandle et était toujours en cours d’exécution lorsque cette fonction a été appelée.

(DM) SQLExecute, SQLExecDirect, SQLBulkOperations ou SQLSetPos a été appelé pour l’InstructionHandle et a retourné SQL_NEED_DATA. Cette fonction a été appelée avant l’envoi des données pour toutes les colonnes ou paramètres de données au moment de l’exécution.

(DM) L’InstructionHandle était dans un état exécuté, mais aucun jeu de résultats n’a été associé à l’InstructionHandle.

Un appel à SQLExeceute, SQLExecDirect ou SQLMoreResults a retourné SQL_PARAM_DATA_AVAILABLE, mais SQLGetData a été appelé, au lieu de SQLParamData.
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, peut-être en raison de conditions de mémoire insuffisantes.
HY090 Chaîne ou longueur de mémoire tampon non valide (DM) La valeur spécifiée pour l’argument BufferLength était inférieure à 0.

La valeur spécifiée pour l’argument BufferLength était inférieure à 4, l’argument Col_or_Param_Num a été défini sur 0 et le pilote était un pilote ODBC 2*.x*.
HY109 Position du curseur non valide Le curseur a été positionné (par SQLSetPos, SQLFetch, SQLFetchScroll ou SQLBulkOperations) sur une ligne qui avait été supprimée ou qui n’a pas pu être extraite.

Le curseur était un curseur avant uniquement et la taille de l’ensemble de lignes était supérieure à un.
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.
HYC00 Fonctionnalité facultative non implémentée Le pilote ou la source de données ne prend pas en charge l’utilisation de SQLGetData avec plusieurs lignes dans SQLFetchScroll. Cette description ne s’applique pas aux pilotes qui retournent le masque de bits SQL_GD_BLOCK pour l’option SQL_GETDATA_EXTENSIONS dans SQLGetInfo.

Le pilote ou la source de données ne prend pas en charge la conversion spécifiée par la combinaison de l’argument TargetType et du type de données SQL de la colonne correspondante. Cette erreur s’applique uniquement lorsque le type de données SQL de la colonne a été mappé à un type de données SQL spécifique au pilote.

Le pilote prend uniquement en charge ODBC 2*.x*, et l’argument TargetType était l’un des suivants :

SQL_C_NUMERIC SQL_C_SBIGINT SQL_C_UBIGINT

et l’un des types de données interval C répertoriés dans Types de données C dans l’Annexe D : Types de données.

Le pilote prend uniquement en charge les versions ODBC antérieures à 3.50, et l’argument TargetType a été SQL_C_GUID.
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 ne réponde à la demande. Le délai d’expiration de connexion est défini via SQLSetConnectAttr, SQL_ATTR_CONNECTION_TIMEOUT.
IM001 Le pilote ne prend pas en charge cette fonction (DM) Le pilote correspondant à 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 le post-traitement et terminer l’opération.

Commentaires

SQLGetData retourne les données dans une colonne spécifiée. SQLGetData peut être appelé uniquement après qu’une ou plusieurs lignes ont été extraites du jeu de résultats par SQLFetch, SQLFetchScroll ou SQLExtendedFetch. Si les données de longueur variable sont trop volumineuses pour être retournées dans un seul appel à SQLGetData (en raison d’une limitation dans l’application), SQLGetData peut les récupérer en parties. Il est possible de lier certaines colonnes dans une ligne et d’appeler SQLGetData pour d’autres, bien que cela soit soumis à certaines restrictions. Pour plus d’informations, consultez Obtention de données longues.

Pour plus d’informations sur l’utilisation de SQLGetData avec des paramètres de sortie diffusés en continu, consultez Récupération des paramètres de sortie à l’aide de SQLGetData.

Utilisation de SQLGetData

Si le pilote ne prend pas en charge les extensions de SQLGetData, la fonction peut retourner des données uniquement pour les colonnes indépendantes dont le nombre est supérieur à celui de la dernière colonne liée. En outre, dans une ligne de données, la valeur de l’argument Col_or_Param_Num dans chaque appel à SQLGetData doit être supérieure ou égale à la valeur de Col_or_Param_Num dans l’appel précédent ; Autrement dit, les données doivent être récupérées dans l’ordre croissant du numéro de colonne. Enfin, si aucune extension n’est prise en charge, SQLGetData ne peut pas être appelé si la taille de l’ensemble de lignes est supérieure à 1.

Les conducteurs peuvent assouplir l’une de ces restrictions. Pour déterminer les restrictions qu’un pilote assouplit, une application appelle SQLGetInfo avec l’une des options de SQL_GETDATA_EXTENSIONS suivantes :

  • SQL_GD_OUTPUT_PARAMS = SQLGetData peut être appelé pour retourner des valeurs de paramètre de sortie. Pour plus d’informations, consultez Récupération des paramètres de sortie à l’aide de SQLGetData.

  • SQL_GD_ANY_COLUMN. Si cette option est retournée, SQLGetData peut être appelé pour n’importe quelle colonne non liée, y compris celles antérieures à la dernière colonne liée.

  • SQL_GD_ANY_ORDER. Si cette option est retournée, SQLGetData peut être appelé pour les colonnes non liées dans n’importe quel ordre.

  • SQL_GD_BLOCK. Si cette option est retournée par SQLGetInfo pour l’SQL_GETDATA_EXTENSIONS InfoType, le pilote prend en charge les appels à SQLGetData lorsque la taille de l’ensemble de lignes est supérieure à 1 et l’application peut appeler SQLSetPos avec l’option SQL_POSITION pour positionner le curseur sur la ligne appropriée avant d’appeler SQLGetData.

  • SQL_GD_BOUND. Si cette option est retournée, SQLGetData peut être appelé pour les colonnes liées ainsi que pour les colonnes non liées.

Il existe deux exceptions à ces restrictions et la capacité d’un conducteur à les assouplir. Tout d’abord, SQLGetData ne doit jamais être appelé pour un curseur avant uniquement lorsque la taille de l’ensemble de lignes est supérieure à 1. Deuxièmement, si un pilote prend en charge les signets, il doit toujours prendre en charge la possibilité d’appeler SQLGetData pour la colonne 0, même s’il ne permet pas aux applications d’appeler SQLGetData pour d’autres colonnes avant la dernière colonne liée. (Lorsqu’une application fonctionne avec un pilote ODBC 2*.x*, SQLGetData retourne correctement un signet lorsqu’il est appelé avec Col_or_Param_Num égal à 0 après un appel à SQLFetch, car SQLFetch est mappé par le Gestionnaire de pilotes ODBC 3*.x* à SQLExtendedFetch avec un FetchOrientation de SQL_FETCH_NEXT, et SQLGetData avec un Col_or_Param_Num de 0 est mappé par le Gestionnaire de pilotes ODBC 3*.x* à SQLGetStmtOption avec un fOption de SQL_GET_BOOKMARK.)

SQLGetData ne peut pas être utilisé pour récupérer le signet d’une ligne qui vient d’être insérée en appelant SQLBulkOperations avec l’option SQL_ADD, car le curseur n’est pas positionné sur la ligne. Une application peut récupérer le signet d’une telle ligne en liant la colonne 0 avant d’appeler SQLBulkOperations avec SQL_ADD, auquel cas SQLBulkOperations retourne le signet dans la mémoire tampon liée. SQLFetchScroll peut ensuite être appelé avec SQL_FETCH_BOOKMARK pour repositionner le curseur sur cette ligne.

Si l’argument TargetType est un type de données d’intervalle, l’intervalle par défaut de précision de début (2) et la précision de l’intervalle par défaut en secondes (6), tels que définis dans les champs SQL_DESC_DATETIME_INTERVAL_PRECISION et SQL_DESC_PRECISION de l’ARD, respectivement, sont utilisés pour les données. Si l’argument TargetType est un type de données SQL_C_NUMERIC, la précision par défaut (définie par le pilote) et l’échelle par défaut (0), telles que définies dans les champs SQL_DESC_PRECISION et SQL_DESC_SCALE de l’ARD, sont utilisées pour les données. Si une précision ou une échelle par défaut n’est pas appropriée, l’application doit explicitement définir le champ de descripteur approprié par un appel à SQLSetDescField ou SQLSetDescRec. Il peut définir le champ SQL_DESC_CONCISE_TYPE sur SQL_C_NUMERIC et appeler SQLGetData avec un argument TargetType de SQL_ARD_TYPE, ce qui entraîne l’utilisation des valeurs de précision et de mise à l’échelle dans les champs de descripteur.

Notes

Dans ODBC 2*.x*, les applications définissent TargetType sur SQL_C_DATE, SQL_C_TIME ou SQL_C_TIMESTAMP pour indiquer que *TargetValuePtr est une structure de date, d’heure ou d’horodatage. Dans ODBC 3*.x*, les applications définissent TargetType sur SQL_C_TYPE_DATE, SQL_C_TYPE_TIME ou SQL_C_TYPE_TIMESTAMP. Le Gestionnaire de pilotes effectue des mappages appropriés si nécessaire, en fonction de l’application et de la version du pilote.

Récupération de données Variable-Length en parties

SQLGetData peut être utilisé pour récupérer des données à partir d’une colonne qui contient des données de longueur variable en parties, c’est-à-dire lorsque l’identificateur du type de données SQL de la colonne est SQL_CHAR, SQL_VARCHAR, SQL_LONGVARCHAR, SQL_WCHAR, SQL_WVARCHAR, SQL_WLONGVARCHAR, SQL_BINARY, SQL_VARBINARY, SQL_LONGVARBINARY ou un identificateur spécifique au pilote pour un type de longueur variable.

Pour récupérer des données d’une colonne en parties, l’application appelle SQLGetData plusieurs fois successivement pour la même colonne. À chaque appel, SQLGetData retourne la partie suivante des données. Il appartient à l’application de réassembler les parties, en prenant soin de supprimer le caractère d’arrêt null des parties intermédiaires des données de caractères. S’il y a plus de données à retourner ou si la mémoire tampon n’a pas été allouée suffisamment pour le caractère de fin, SQLGetData retourne SQL_SUCCESS_WITH_INFO et SQLSTATE 01004 (données tronquées). Lorsqu’il retourne la dernière partie des données, SQLGetData retourne SQL_SUCCESS. Ni SQL_NO_TOTAL ni zéro ne peuvent être retournés lors du dernier appel valide pour récupérer des données à partir d’une colonne, car l’application n’aurait alors aucun moyen de savoir quelle quantité de données dans la mémoire tampon de l’application est valide. Si SQLGetData est appelé après cela, il retourne SQL_NO_DATA. Pour plus d’informations, consultez la section suivante, « Récupération de données avec SQLGetData ».

Les signets de longueur variable peuvent être retournés en parties par SQLGetData. Comme pour d’autres données, un appel à SQLGetData pour retourner des signets de longueur variable en parties renvoie SQLSTATE 01004 (Données de chaîne, tronquées à droite) et SQL_SUCCESS_WITH_INFO quand il y a plus de données à retourner. Cela est différent du cas lorsqu’un signet de longueur variable est tronqué par un appel à SQLFetch ou SQLFetchScroll, qui retourne SQL_ERROR et SQLSTATE 22001 (données string, tronquées à droite).

SQLGetData ne peut pas être utilisé pour retourner des données de longueur fixe en parties. Si SQLGetData est appelé plusieurs fois dans une ligne pour une colonne contenant des données de longueur fixe, il retourne SQL_NO_DATA pour tous les appels après le premier.

Récupération des paramètres de sortie en continu

Si un pilote prend en charge les paramètres de sortie en continu, une application peut appeler SQLGetData avec une petite mémoire tampon plusieurs fois pour récupérer une grande valeur de paramètre. Pour plus d’informations sur le paramètre de sortie en continu, consultez Récupération des paramètres de sortie à l’aide de SQLGetData.

Récupération de données avec SQLGetData

Pour retourner des données pour la colonne spécifiée, SQLGetData effectue la séquence d’étapes suivante :

  1. Retourne SQL_NO_DATA s’il a déjà retourné toutes les données de la colonne.

  2. Définit *StrLen_or_IndPtr sur SQL_NULL_DATA si les données ont la valeur NULL. Si les données ont la valeur NULL et StrLen_or_IndPtr était un pointeur null, SQLGetData retourne SQLSTATE 22002 (variable d’indicateur requise mais non fournie).

    Si les données de la colonne n’ont pas la valeur NULL, SQLGetData passe à l’étape 3.

  3. Si l’attribut d’instruction SQL_ATTR_MAX_LENGTH est défini sur une valeur différente de zéro, si la colonne contient des données caractère ou binaires et si SQLGetData n’a pas encore été appelé pour la colonne, les données sont tronquées à SQL_ATTR_MAX_LENGTH octets.

    Notes

    L’attribut d’instruction SQL_ATTR_MAX_LENGTH est destiné à réduire le trafic réseau. Il est généralement implémenté par la source de données, qui tronque les données avant de les renvoyer sur le réseau. Les pilotes et les sources de données ne sont pas nécessaires pour le prendre en charge. Par conséquent, pour garantir que les données sont tronquées à une taille particulière, une application doit allouer une mémoire tampon de cette taille et spécifier la taille dans l’argument BufferLength .

  4. Convertit les données au type spécifié dans TargetType. Les données reçoivent la précision et l’échelle par défaut pour ce type de données. Si TargetType est SQL_ARD_TYPE, le type de données dans le champ SQL_DESC_CONCISE_TYPE de l’ARD est utilisé. Si TargetType est SQL_ARD_TYPE, les données reçoivent la précision et l’échelle dans les champs SQL_DESC_DATETIME_INTERVAL_PRECISION, SQL_DESC_PRECISION et SQL_DESC_SCALE de l’ARD, en fonction du type de données dans le champ SQL_DESC_CONCISE_TYPE. Si une précision ou une échelle par défaut n’est pas appropriée, l’application doit explicitement définir le champ de descripteur approprié par un appel à SQLSetDescField ou SQLSetDescRec.

  5. Si les données ont été converties en un type de données de longueur variable, tel que caractère ou binaire, SQLGetData vérifie si la longueur des données dépasse BufferLength. Si la longueur des données de caractère (y compris le caractère de terminaison null) dépasse BufferLength, SQLGetData tronque les données en BufferLength moins la longueur d’un caractère de terminaison null. Les données sont alors terminées par la valeur null. Si la longueur des données binaires dépasse la longueur de la mémoire tampon de données, SQLGetData les tronque en octets BufferLength .

    Si la mémoire tampon de données fournie est trop petite pour contenir le caractère d’arrêt null, SQLGetData retourne SQL_SUCCESS_WITH_INFO et SQLSTATE 01004.

    SQLGetData ne tronque jamais les données converties en types de données de longueur fixe ; il suppose toujours que la longueur de *TargetValuePtr est la taille du type de données.

  6. Place les données converties (et éventuellement tronquées) dans *TargetValuePtr. Notez que SQLGetData ne peut pas retourner des données hors ligne.

  7. Place la longueur des données dans *StrLen_or_IndPtr. Si StrLen_or_IndPtr était un pointeur null, SQLGetData ne retourne pas la longueur.

    • Pour les données caractère ou binaires, il s’agit de la longueur des données après la conversion et avant la troncation due à BufferLength. Si le pilote ne peut pas déterminer la longueur des données après la conversion, comme c’est parfois le cas avec les données longues, il retourne SQL_SUCCESS_WITH_INFO et définit la longueur sur SQL_NO_TOTAL. (Le dernier appel à SQLGetData doit toujours retourner la longueur des données, et non zéro ou SQL_NO_TOTAL.) Si les données ont été tronquées en raison de l’attribut d’instruction SQL_ATTR_MAX_LENGTH, la valeur de cet attribut ( par opposition à la longueur réelle ) est placée dans *StrLen_or_IndPtr. En effet, cet attribut est conçu pour tronquer des données sur le serveur avant la conversion, de sorte que le pilote n’a aucun moyen de déterminer la longueur réelle. Lorsque SQLGetData est appelé plusieurs fois successivement pour la même colonne, il s’agit de la longueur des données disponibles au début de l’appel en cours ; autrement dit, la longueur diminue à chaque appel suivant.

    • Pour tous les autres types de données, il s’agit de la longueur des données après la conversion ; autrement dit, il s’agit de la taille du type vers lequel les données ont été converties.

  8. Si les données sont tronquées sans perte de signification pendant la conversion (par exemple, le nombre réel 1.234 est tronqué lors de la conversion en entier 1) ou parce que BufferLength est trop petit (par exemple, la chaîne « abcdef » est placée dans une mémoire tampon de 4 octets), SQLGetData retourne SQLSTATE 01004 (Données tronquées) et SQL_SUCCESS_WITH_INFO. Si les données sont tronquées sans perte de signification en raison de l’attribut d’instruction SQL_ATTR_MAX_LENGTH, SQLGetData retourne SQL_SUCCESS et ne retourne pas SQLSTATE 01004 (données tronquées).

Le contenu de la mémoire tampon de données liée (si SQLGetData est appelé sur une colonne liée) et la mémoire tampon de longueur/indicateur ne sont pas définis si SQLGetData ne retourne pas SQL_SUCCESS ou SQL_SUCCESS_WITH_INFO.

Les appels successifs à SQLGetData récupèrent les données de la dernière colonne demandée ; les décalages antérieurs deviennent non valides. Par exemple, lorsque la séquence suivante est effectuée :

SQLGetData(icol=n), SQLGetData(icol=m), SQLGetData(icol=n)  

le deuxième appel à SQLGetData(icol=n) récupère les données au début de la colonne n. Tout décalage dans les données en raison d’appels antérieurs à SQLGetData pour la colonne n’est plus valide.

Descripteurs et SQLGetData

SQLGetData n’interagit pas directement avec les champs de descripteur.

Si TargetType est SQL_ARD_TYPE, le type de données dans le champ SQL_DESC_CONCISE_TYPE de l’ARD est utilisé. Si TargetType est SQL_ARD_TYPE ou SQL_C_DEFAULT, les données reçoivent la précision et l’échelle dans les champs SQL_DESC_DATETIME_INTERVAL_PRECISION, SQL_DESC_PRECISION et SQL_DESC_SCALE de l’ARD, en fonction du type de données dans le champ SQL_DESC_CONCISE_TYPE.

Exemple de code

Dans l’exemple suivant, une application exécute une instruction SELECT pour renvoyer un jeu de résultats des ID client, des noms et des numéros de téléphone triés par nom, ID et numéro de téléphone. Pour chaque ligne de données, il appelle SQLFetch pour positionner le curseur sur la ligne suivante. Il appelle SQLGetData pour récupérer les données extraites ; les mémoires tampons pour les données et le nombre d’octets retournés sont spécifiés dans l’appel à SQLGetData. Enfin, il imprime le nom, l’ID et le numéro de téléphone de chaque employé.

#define NAME_LEN 50  
#define PHONE_LEN 50  
  
SQLCHAR      szName[NAME_LEN], szPhone[PHONE_LEN];  
SQLINTEGER   sCustID, cbName, cbAge, cbBirthday;  
SQLRETURN    retcode;  
SQLHSTMT     hstmt;  
  
retcode = SQLExecDirect(hstmt,  
   "SELECT CUSTID, NAME, PHONE FROM CUSTOMERS ORDER BY 2, 1, 3",  
   SQL_NTS);  
  
if (retcode == SQL_SUCCESS) {  
   while (TRUE) {  
      retcode = SQLFetch(hstmt);  
      if (retcode == SQL_ERROR || retcode == SQL_SUCCESS_WITH_INFO) {  
         show_error();  
      }  
      if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO){  
  
         /* Get data for columns 1, 2, and 3 */  
  
         SQLGetData(hstmt, 1, SQL_C_ULONG, &sCustID, 0, &cbCustID);  
         SQLGetData(hstmt, 2, SQL_C_CHAR, szName, NAME_LEN, &cbName);  
         SQLGetData(hstmt, 3, SQL_C_CHAR, szPhone, PHONE_LEN,  
            &cbPhone);  
  
         /* Print the row of data */  
  
         fprintf(out, "%-5d %-*s %*s", sCustID, NAME_LEN-1, szName,   
            PHONE_LEN-1, szPhone);  
      } else {  
         break;  
      }  
   }  
}  
Pour obtenir des informations sur Consultez
Affectation de stockage pour une colonne dans un jeu de résultats SQLBindCol
Exécution d’opérations en bloc qui ne sont pas liées à la position du curseur de bloc SQLBulkOperations
Annulation du traitement des instructions SQLCancel
Exécution d’une instruction SQL SQLExecDirect
Exécution d’une instruction SQL préparée SQLExecute
Extraction d’un bloc de données ou défilement d’un jeu de résultats SQLFetchScroll
Extraction d’une seule ligne de données ou d’un bloc de données dans une direction avant uniquement SQLFetch
Envoi de données de paramètre au moment de l’exécution SQLPutData
Positionnement du curseur, actualisation des données dans l’ensemble de lignes ou mise à jour ou suppression de données dans l’ensemble de lignes SQLSetPos

Voir aussi

Informations de référence sur l’API ODBC
Fichiers d’en-tête ODBC
Récupération des paramètres de sortie à l’aide de SQLGetData