Partage via


Fonction SQLBindCol

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

Résumé
SQLBindCol lie les mémoires tampons de données d’application aux colonnes du jeu de résultats.

Syntaxe

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

Arguments

StatementHandle
[Entrée] Handle d’instruction.

ColumnNumber
[Entrée] Numéro de la colonne du jeu de résultats à lier. Les colonnes sont numérotées dans l’ordre croissant des colonnes à partir de 0, la colonne 0 étant la colonne des signets. Si les signets ne sont pas utilisés (autrement dit, l’attribut d’instruction SQL_ATTR_USE_BOOKMARKS est défini sur SQL_UB_OFF ), les numéros de colonne commencent à 1.

TargetType
[Entrée] Identificateur du type de données C de la mémoire tampon *TargetValuePtr . Lorsqu’il récupère des données à partir de la source de données avec SQLFetch, SQLFetchScroll, SQLBulkOperations ou SQLSetPos, le pilote convertit les données en ce type ; lorsqu’il envoie des données à la source de données avec SQLBulkOperations ou SQLSetPos, le pilote convertit les données de ce type. 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 l’argument TargetType est un type de données d’intervalle, la précision de début d’intervalle par défaut (2) et la précision d’intervalle secondes par défaut (6), telles que définies dans les champs SQL_DESC_DATETIME_INTERVAL_PRECISION et SQL_DESC_PRECISION de l’ARD, respectivement, sont utilisées pour les données. Si l’argument TargetType est 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 définir explicitement le champ de descripteur approprié par un appel à SQLSetDescField ou SQLSetDescRec.

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
[Entrée/sortie différée] Pointeur vers la mémoire tampon de données à lier à la colonne. SQLFetch et SQLFetchScroll retournent des données dans cette mémoire tampon. SQLBulkOperations retourne des données dans cette mémoire tampon lorsque Operation est SQL_FETCH_BY_BOOKMARK ; il récupère les données de cette mémoire tampon lorsque Operation est SQL_ADD ou SQL_UPDATE_BY_BOOKMARK. SQLSetPos retourne des données dans cette mémoire tampon lorsque Operation est SQL_REFRESH ; il récupère les données de cette mémoire tampon lorsque Operation est SQL_UPDATE.

Si TargetValuePtr est un pointeur null, le pilote dissocie la mémoire tampon de données de la colonne. Une application peut dissocier toutes les colonnes en appelant SQLFreeStmt avec l’option SQL_UNBIND. Une application peut dissocier la mémoire tampon de données d’une colonne, mais avoir toujours une mémoire tampon de longueur/d’indicateur liée à la colonne, si l’argument TargetValuePtr dans l’appel à SQLBindCol est un pointeur Null, mais que l’argument StrLen_or_IndPtr est une valeur valide.

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 lorsqu’il retourne des données de longueur variable, telles que des données caractères ou binaires. Notez que le pilote compte le caractère d’arrêt Null lorsqu’il retourne des 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. Par conséquent, il est 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.

SQLBindCol 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. Toutefois, si TargetType spécifie un type de caractère, une application ne doit pas définir BufferLength sur 0, car les pilotes conformes à l’interface CLI ISO retournent SQLSTATE HY090 (chaîne ou longueur de mémoire tampon non valide) dans ce cas.

StrLen_or_IndPtr
[Entrée/sortie différée] Pointeur vers la mémoire tampon de longueur/d’indicateur à lier à la colonne. SQLFetch et SQLFetchScroll retournent une valeur dans cette mémoire tampon. SQLBulkOperations récupère une valeur de cette mémoire tampon lorsque Operation est SQL_ADD, SQL_UPDATE_BY_BOOKMARK ou SQL_DELETE_BY_BOOKMARK. SQLBulkOperations retourne une valeur dans cette mémoire tampon lorsque Operation est SQL_FETCH_BY_BOOKMARK. SQLSetPos retourne une valeur dans cette mémoire tampon lorsque Operation est SQL_REFRESH ; il récupère une valeur de cette mémoire tampon lorsque Operation est SQL_UPDATE.

SQLFetch, SQLFetchScroll, SQLBulkOperations et SQLSetPos peuvent retourner les valeurs suivantes dans la mémoire tampon length/indicator :

  • Longueur des données disponibles à retourner

  • SQL_NO_TOTAL

  • SQL_NULL_DATA

L’application peut placer les valeurs suivantes dans la mémoire tampon de longueur/d’indicateur à utiliser avec SQLBulkOperations ou SQLSetPos :

  • Longueur des données envoyées

  • SQL_NTS

  • SQL_NULL_DATA

  • SQL_DATA_AT_EXEC

  • Résultat de la macro SQL_LEN_DATA_AT_EXEC

  • SQL_COLUMN_IGNORE

Si la mémoire tampon d’indicateur et la mémoire tampon de longueur sont des mémoires tampons distinctes, la mémoire tampon d’indicateur peut retourner uniquement SQL_NULL_DATA, tandis que la mémoire tampon de longueur peut retourner toutes les autres valeurs.

Pour plus d’informations, consultez Fonction SQLBulkOperations, Fonction SQLFetch, Fonction SQLSetPos et Utilisation de valeurs de longueur/d’indicateur.

Si StrLen_or_IndPtr est un pointeur Null, aucune longueur ou valeur d’indicateur n’est utilisée. Il s’agit d’une erreur lors de l’extraction de données et les données ont la valeur NULL.

Consultez Informations ODBC 64 bits, si votre application s’exécute sur un système d’exploitation 64 bits.

Retours

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR ou SQL_INVALID_HANDLE.

Diagnostics

Lorsque SQLBindCol 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 généralement retournées par SQLBindCol 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.)
07006 Violation d’attribut de type de données restreint (DM) L’argument ColumnNumber était 0, et l’argument TargetType n’était pas SQL_C_BOOKMARK ni SQL_C_VARBOOKMARK.
07009 Index de descripteur non valide La valeur spécifiée pour l’argument ColumnNumber a dépassé le nombre maximal de colonnes dans le 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 mémoire tampon d’application non valide L’argument TargetType n’était ni un type de données valide ni SQL_C_DEFAULT.
HY010 Erreur de séquence de fonction (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 SQLBindCol a été appelé.

(DM) SQLExecute, SQLExecDirect ou SQLMoreResults a été appelé pour l’InstructionHandle 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 en continu.

(DM) Une fonction en cours d’exécution asynchrone 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.
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.
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.

(DM) Le pilote était odbc 2. x pilote, l’argument ColumnNumber a été défini sur 0 et la valeur spécifiée pour l’argument BufferLength n’était pas égale à 4.
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 la conversion spécifiée par la combinaison de l’argument TargetType et du type de données SQL spécifique au pilote de la colonne correspondante.

L’argument ColumnNumber était 0 et le pilote ne prend pas en charge les signets.

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

SQL_C_NUMERIC SQL_C_SBIGINT SQL_C_UBIGINT

et l’un des types de données C d’intervalle 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 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.

Commentaires

SQLBindCol est utilisé pour associer ou lier des colonnes du jeu de résultats aux mémoires tampons de données et aux mémoires tampons de longueur/indicateur dans l’application. Lorsque l’application appelle SQLFetch, SQLFetchScroll ou SQLSetPos pour extraire des données, le pilote retourne les données des colonnes liées dans les mémoires tampons spécifiées ; Pour plus d’informations, consultez FONCTION SQLFetch. Lorsque l’application appelle SQLBulkOperations pour mettre à jour ou insérer une ligne ou SQLSetPos pour mettre à jour une ligne, le pilote récupère les données des colonnes liées à partir des mémoires tampons spécifiées ; Pour plus d’informations, consultez FONCTION SQLBulkOperations ou FONCTION SQLSetPos. Pour plus d’informations sur la liaison, consultez Récupération des résultats (de base).

Notez que les colonnes n’ont pas besoin d’être liées pour récupérer des données à partir d’elles. Une application peut également appeler SQLGetData pour récupérer des données à partir de colonnes. Bien qu’il soit possible de lier certaines colonnes dans une ligne et d’appeler SQLGetData pour d’autres, cela est soumis à certaines restrictions. Pour plus d’informations, consultez SQLGetData.

Liaison, dissociation et reliure de colonnes

Une colonne peut être liée, non liée ou rebondir à tout moment, même après que des données ont été extraites du jeu de résultats. La nouvelle liaison prend effet la prochaine fois qu’une fonction qui utilise des liaisons est appelée. Par exemple, supposons qu’une application lie les colonnes d’un jeu de résultats et appelle SQLFetch. Le pilote retourne les données dans les mémoires tampons liées. Supposons maintenant que l’application lie les colonnes à un autre ensemble de mémoires tampons. Le pilote ne place pas les données de la ligne qui vient d’être extraite dans les mémoires tampons nouvellement liées. Au lieu de cela, il attend que SQLFetch soit appelé à nouveau, puis place les données de la ligne suivante dans les mémoires tampons nouvellement liées.

Notes

L’attribut d’instruction SQL_ATTR_USE_BOOKMARKS doit toujours être défini avant de lier une colonne à la colonne 0. Cela n’est pas obligatoire, mais est fortement recommandé.

Liaison de colonnes

Pour lier une colonne, une application appelle SQLBindCol et transmet le numéro de colonne, le type, l’adresse et la longueur d’une mémoire tampon de données, ainsi que l’adresse d’une mémoire tampon de longueur/d’indicateur. Pour plus d’informations sur l’utilisation de ces adresses, consultez « Adresses de mémoire tampon », plus loin dans cette section. Pour plus d’informations sur la liaison de colonnes, consultez Utilisation de SQLBindCol.

L’utilisation de ces tampons est différée ; autrement dit, l’application les lie dans SQLBindCol , mais le pilote y accède à partir d’autres fonctions, à savoir SQLBulkOperations, SQLFetch, SQLFetchScroll ou SQLSetPos. Il incombe à l’application de s’assurer que les pointeurs spécifiés dans SQLBindCol restent valides tant que la liaison reste en vigueur. Si l’application autorise ces pointeurs à devenir non valides (par exemple, elle libère une mémoire tampon) et appelle une fonction qui s’attend à ce qu’ils soient valides, les conséquences ne sont pas définies. Pour plus d’informations, consultez Mémoires tampons différées.

La liaison reste en vigueur jusqu’à ce qu’elle soit remplacée par une nouvelle liaison, que la colonne ne soit pas lié ou que l’instruction soit libérée.

Dissociation des colonnes

Pour dissocier une colonne unique, une application appelle SQLBindCol avec ColumnNumber défini sur le numéro de cette colonne et TargetValuePtr défini sur un pointeur null. Si ColumnNumber fait référence à une colonne non lié, SQLBindCol retourne toujours SQL_SUCCESS.

Pour dissocier toutes les colonnes, une application appelle SQLFreeStmt avec fOption défini sur SQL_UNBIND. Pour ce faire, définissez le champ SQL_DESC_COUNT de l’ARD sur zéro.

Reliure de colonnes

Une application peut effectuer l’une des deux opérations pour modifier une liaison :

  • Appelez SQLBindCol pour spécifier une nouvelle liaison pour une colonne déjà liée. Le pilote remplace l’ancienne liaison par la nouvelle.

  • Spécifiez un décalage à ajouter à l’adresse de mémoire tampon spécifiée par l’appel de liaison à SQLBindCol. Pour plus d’informations, consultez la section suivante, « Décalages de liaison ».

Décalages de liaison

Un décalage de liaison est une valeur ajoutée aux adresses des mémoires tampons de données et de longueur/indicateur (comme spécifié dans l’argument TargetValuePtr et StrLen_or_IndPtr ) avant qu’elles ne soient déréférencées. Lorsque des décalages sont utilisés, les liaisons sont un « modèle » de la façon dont les mémoires tampons de l’application sont disposées, et l’application peut déplacer ce « modèle » vers différentes zones de mémoire en modifiant le décalage. Étant donné que le même décalage est ajouté à chaque adresse dans chaque liaison, les décalages relatifs entre les mémoires tampons pour différentes colonnes doivent être les mêmes dans chaque ensemble de mémoires tampons. Cela est toujours vrai lorsque la liaison en ligne est utilisée ; l’application doit disposer soigneusement ses mémoires tampons pour que cela soit vrai lors de l’utilisation d’une liaison au niveau des colonnes.

L’utilisation d’un décalage de liaison a essentiellement le même effet que la reliure d’une colonne en appelant SQLBindCol. La différence est qu’un nouvel appel à SQLBindCol spécifie de nouvelles adresses pour la mémoire tampon de données et la mémoire tampon longueur/indicateur, alors que l’utilisation d’un décalage de liaison ne modifie pas les adresses, mais leur ajoute simplement un décalage. L’application peut spécifier un nouveau décalage chaque fois qu’elle le souhaite, et ce décalage est toujours ajouté aux adresses liées d’origine. En particulier, si le décalage est défini sur 0 ou si l’attribut d’instruction est défini sur un pointeur null, le pilote utilise les adresses liées d’origine.

Pour spécifier un décalage de liaison, l’application définit l’attribut d’instruction SQL_ATTR_ROW_BIND_OFFSET_PTR sur l’adresse d’une mémoire tampon SQLINTEGER. Avant que l’application appelle une fonction qui utilise des liaisons, elle place un décalage en octets dans cette mémoire tampon. Pour déterminer l’adresse de la mémoire tampon à utiliser, le pilote ajoute le décalage à l’adresse dans la liaison. La somme de l’adresse et du décalage doit être une adresse valide, mais l’adresse à laquelle le décalage est ajouté n’a pas besoin d’être valide. Pour plus d’informations sur l’utilisation des décalages de liaison, consultez « Adresses de mémoire tampon », plus loin dans cette section.

Tableaux de liaison

Si la taille de l’ensemble de lignes (la valeur de l’attribut d’instruction SQL_ATTR_ROW_ARRAY_SIZE) est supérieure à 1, l’application lie des tableaux de mémoires tampons au lieu de mémoires tampons uniques. Pour plus d’informations, consultez Bloquer les curseurs.

L’application peut lier des tableaux de deux manières :

  • Lier un tableau à chaque colonne. Il s’agit d’une liaison par colonne , car chaque structure de données (tableau) contient des données pour une seule colonne.

  • Définissez une structure pour contenir les données d’une ligne entière et liez un tableau de ces structures. Il s’agit d’une liaison par ligne , car chaque structure de données contient les données d’une seule ligne.

Chaque tableau de mémoires tampons doit avoir au moins autant d’éléments que la taille de l’ensemble de lignes.

Notes

Une application doit vérifier que l’alignement est valide. Pour plus d’informations sur les considérations relatives à l’alignement, consultez Alignement.

Liaison selon les colonnes

Dans la liaison au niveau des colonnes, l’application lie des tableaux de données et de longueurs/indicateurs distincts à chaque colonne.

Pour utiliser la liaison par colonne, l’application définit d’abord l’attribut d’instruction SQL_ATTR_ROW_BIND_TYPE sur SQL_BIND_BY_COLUMN. (Il s’agit de la valeur par défaut.) Pour que chaque colonne soit liée, l’application effectue les étapes suivantes :

  1. Alloue un tableau de mémoire tampon de données.

  2. Alloue un tableau de mémoires tampons de longueur/indicateur.

    Notes

    Si l’application écrit directement dans les descripteurs lors de l’utilisation d’une liaison au niveau des colonnes, des tableaux distincts peuvent être utilisés pour les données de longueur et d’indicateur.

  3. Appelle SQLBindCol avec les arguments suivants :

    • TargetType est le type d’un élément unique dans le tableau de mémoires tampons de données.

    • TargetValuePtr est l’adresse du tableau de mémoires tampons de données.

    • BufferLength est la taille d’un élément unique dans le tableau de mémoires tampons de données. L’argument BufferLength est ignoré lorsque les données sont de longueur fixe.

    • StrLen_or_IndPtr est l’adresse du tableau de longueurs/indicateurs.

Pour plus d’informations sur la façon dont ces informations sont utilisées, consultez « Adresses de mémoire tampon », plus loin dans cette section. Pour plus d’informations sur la liaison au niveau des colonnes, consultez Liaison au niveau des colonnes.

Liaison selon les lignes

Dans la liaison au niveau des lignes, l’application définit une structure qui contient des mémoires tampons de données et de longueur/indicateur pour chaque colonne à lier.

Pour utiliser la liaison au niveau des lignes, l’application effectue les étapes suivantes :

  1. Définit une structure pour contenir une seule ligne de données (y compris les mémoires tampons de données et de longueur/indicateur) et alloue un tableau de ces structures.

    Notes

    Si l’application écrit directement dans les descripteurs lors de l’utilisation d’une liaison au niveau des lignes, des champs distincts peuvent être utilisés pour les données de longueur et d’indicateur.

  2. Définit l’attribut d’instruction SQL_ATTR_ROW_BIND_TYPE sur la taille de la structure qui contient une seule ligne de données ou sur la taille d’une instance d’une mémoire tampon dans laquelle les colonnes de résultats seront liées. La longueur doit inclure de l’espace pour toutes les colonnes liées, et tout remplissage de la structure ou de la mémoire tampon, pour s’assurer que lorsque l’adresse d’une colonne liée est incrémentée avec la longueur spécifiée, le résultat pointe vers le début de la même colonne dans la ligne suivante. Lors de l’utilisation de l’opérateur sizeof dans ANSI C, ce comportement est garanti.

  3. Appelle SQLBindCol avec les arguments suivants pour que chaque colonne soit liée :

    • TargetType est le type du membre de mémoire tampon de données à lier à la colonne.

    • TargetValuePtr est l’adresse du membre de mémoire tampon de données dans le premier élément de tableau.

    • BufferLength est la taille du membre de la mémoire tampon de données.

    • StrLen_or_IndPtr est l’adresse du membre de longueur/indicateur à lier.

Pour plus d’informations sur la façon dont ces informations sont utilisées, consultez « Adresses de mémoire tampon », plus loin dans cette section. Pour plus d’informations sur la liaison au niveau des colonnes, consultez Liaison au niveau des lignes.

Adresses de mémoire tampon

L’adresse de la mémoire tampon est l’adresse réelle de la mémoire tampon des données ou de la longueur/de l’indicateur. Le pilote calcule l’adresse de la mémoire tampon juste avant d’écrire dans les mémoires tampons (par exemple, pendant l’extraction). Il est calculé à partir de la formule suivante, qui utilise les adresses spécifiées dans les arguments TargetValuePtr et StrLen_or_IndPtr , le décalage de liaison et le numéro de ligne :

Adresse + liée Décalage de liaison + ((numéro de ligne - 1) x taille d’élément)

où les variables de la formule sont définies comme décrit dans le tableau suivant.

Variable Description
Adresse liée Pour les mémoires tampons de données, adresse spécifiée avec l’argument TargetValuePtr dans SQLBindCol.

Pour les mémoires tampons de longueur/d’indicateur, l’adresse spécifiée avec l’argument StrLen_or_IndPtr dans SQLBindCol. Pour plus d’informations, consultez « Commentaires supplémentaires » dans la section « Descripteurs et SQLBindCol ».

Si l’adresse liée est 0, aucune valeur de données n’est retournée, même si l’adresse calculée par la formule précédente est différente de zéro.
Décalage de liaison Si la liaison au niveau des lignes est utilisée, la valeur stockée à l’adresse spécifiée avec l’attribut d’instruction SQL_ATTR_ROW_BIND_OFFSET_PTR.

Si la liaison au niveau des colonnes est utilisée ou si la valeur de l’attribut d’instruction SQL_ATTR_ROW_BIND_OFFSET_PTR est un pointeur Null, l’offset de liaison est égal à 0.
Row Number Numéro de base 1 de la ligne dans l’ensemble de lignes. Pour les extractions à ligne unique, qui sont la valeur par défaut, il s’agit de 1.
Taille de l’élément Taille d’un élément dans le tableau lié.

Si une liaison au niveau des colonnes est utilisée, il s’agit de sizeof(SQLINTEGER) pour les mémoires tampons de longueur/d’indicateur. Pour les mémoires tampons de données, il s’agit de la valeur de l’argument BufferLength dans SQLBindCol si le type de données est de longueur variable, et de la taille du type de données si le type de données est de longueur fixe.

Si la liaison au niveau des lignes est utilisée, il s’agit de la valeur de l’attribut d’instruction SQL_ATTR_ROW_BIND_TYPE pour les mémoires tampons de données et de longueur/d’indicateur.

Descripteurs et SQLBindCol

Les sections suivantes décrivent comment SQLBindCol interagit avec les descripteurs.

Attention

L’appel de SQLBindCol pour une instruction peut affecter d’autres instructions. Cela se produit lorsque l’ARD associé à l’instruction est explicitement alloué et est également associé à d’autres instructions. Étant donné que SQLBindCol modifie le descripteur, les modifications s’appliquent à toutes les instructions auxquelles ce descripteur est associé. Si ce n’est pas le comportement requis, l’application doit dissocier ce descripteur des autres instructions avant d’appeler SQLBindCol.

Mappages d’arguments

D’un point de vue conceptuel, SQLBindCol effectue les étapes suivantes dans l’ordre :

  1. Appelle SQLGetStmtAttr pour obtenir le handle ARD.

  2. Appelle SQLGetDescField pour obtenir le champ SQL_DESC_COUNT de ce descripteur et, si la valeur de l’argument ColumnNumber dépasse la valeur de SQL_DESC_COUNT, appelle SQLSetDescField pour augmenter la valeur de SQL_DESC_COUNT à ColumnNumber.

  3. Appelle SQLSetDescField plusieurs fois pour affecter des valeurs aux champs suivants de l’ARD :

    • Définit SQL_DESC_TYPE et SQL_DESC_CONCISE_TYPE à la valeur de TargetType, sauf que si TargetType est l’un des identificateurs concis d’un sous-type datetime ou interval, il définit SQL_DESC_TYPE sur SQL_DATETIME ou SQL_INTERVAL, respectivement ; définit SQL_DESC_CONCISE_TYPE à l’identificateur concis ; et définit SQL_DESC_DATETIME_INTERVAL_CODE au sous-code datetime ou interval correspondant.

    • Définit un ou plusieurs des SQL_DESC_LENGTH, SQL_DESC_PRECISION, SQL_DESC_SCALE et SQL_DESC_DATETIME_INTERVAL_PRECISION, selon les besoins de TargetType.

    • Définit le champ SQL_DESC_OCTET_LENGTH sur la valeur de BufferLength.

    • Définit le champ SQL_DESC_DATA_PTR sur la valeur de TargetValuePtr.

    • Définit le champ SQL_DESC_INDICATOR_PTR sur la valeur de StrLen_or_IndPtr. (Voir le paragraphe suivant.)

    • Définit le champ SQL_DESC_OCTET_LENGTH_PTR sur la valeur de StrLen_or_IndPtr. (Voir le paragraphe suivant.)

La variable à laquelle l’argument StrLen_or_IndPtr fait référence est utilisée pour les informations d’indicateur et de longueur. Si une extraction rencontre une valeur Null pour la colonne, elle stocke SQL_NULL_DATA dans cette variable ; sinon, il stocke la longueur des données dans cette variable. Le passage d’un pointeur null comme StrLen_or_IndPtr empêche l’opération d’extraction de retourner la longueur des données, mais fait échouer l’extraction si elle rencontre une valeur null et n’a aucun moyen de retourner SQL_NULL_DATA.

Si l’appel à SQLBindCol échoue, le contenu des champs de descripteur qu’il aurait définis dans l’ARD n’est pas défini et la valeur du champ SQL_DESC_COUNT de l’ARD est inchangée.

Réinitialisation implicite du champ COUNT

SQLBindCol définit SQL_DESC_COUNT sur la valeur de l’argument ColumnNumber uniquement lorsque cela augmente la valeur de SQL_DESC_COUNT. Si la valeur de l’argument TargetValuePtr est un pointeur Null et que la valeur de l’argument ColumnNumber est égale à SQL_DESC_COUNT (autrement dit, lors de la dissociation de la colonne liée la plus élevée), SQL_DESC_COUNT est défini sur le nombre de la colonne liée la plus élevée restante.

Avertissements concernant SQL_DEFAULT

Pour récupérer correctement les données de colonne, l’application doit déterminer correctement la longueur et le point de départ des données dans la mémoire tampon de l’application. Lorsque l’application spécifie un TargetType explicite, des erreurs d’application sont facilement détectées. Toutefois, lorsque l’application spécifie un TargetType de SQL_DEFAULT, SQLBindCol peut être appliqué à une colonne d’un type de données différent de celui prévu par l’application, soit à partir des modifications apportées aux métadonnées, soit en appliquant le code à une autre colonne. Dans ce cas, l’application peut ne pas toujours déterminer le début ou la longueur des données de colonne extraites. Cela peut entraîner des erreurs de données non signalées ou des violations de mémoire.

Exemple de code

Dans l’exemple suivant, une application exécute une instruction SELECT sur la table Customers pour retourner un jeu de résultats des ID, noms et numéros de téléphone des clients, triés par nom. Il appelle ensuite SQLBindCol pour lier les colonnes de données aux mémoires tampons locales. Enfin, l’application extrait chaque ligne de données avec SQLFetch et imprime le nom, l’ID et le numéro de téléphone de chaque client.

Pour obtenir d’autres exemples de code, consultez Fonction SQLBulkOperations, Fonction SQLColumns, FONCTION SQLFetchScroll et FONCTION SQLSetPos.

// SQLBindCol_ref.cpp  
// compile with: odbc32.lib  
#include <windows.h>  
#include <stdio.h>  
  
#define UNICODE  
#include <sqlext.h>  
  
#define NAME_LEN 50  
#define PHONE_LEN 60
  
void show_error() {  
   printf("error\n");  
}  
  
int main() {  
   SQLHENV henv;  
   SQLHDBC hdbc;  
   SQLHSTMT hstmt = 0;  
   SQLRETURN retcode;  
   SQLWCHAR szName[NAME_LEN], szPhone[PHONE_LEN], sCustID[NAME_LEN];  
   SQLLEN cbName = 0, cbCustID = 0, cbPhone = 0;  
  
   // Allocate environment handle  
   retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);  
  
   // Set the ODBC version environment attribute  
   if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
      retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);   
  
      // Allocate connection handle  
      if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
         retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);  
  
         // Set login timeout to 5 seconds  
         if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
            SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);  
  
            // Connect to data source  
            retcode = SQLConnect(hdbc, (SQLWCHAR*) L"NorthWind", SQL_NTS, (SQLWCHAR*) NULL, 0, NULL, 0);  
  
            // Allocate statement handle  
            if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {   
               retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);   
  
               retcode = SQLExecDirect(hstmt, (SQLWCHAR *) L"SELECT CustomerID, ContactName, Phone FROM CUSTOMERS ORDER BY 2, 1, 3", SQL_NTS);  
               if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
  
                  // Bind columns 1, 2, and 3  
                  retcode = SQLBindCol(hstmt, 1, SQL_C_WCHAR, &sCustID, 100, &cbCustID);  
                  retcode = SQLBindCol(hstmt, 2, SQL_C_WCHAR, szName, NAME_LEN, &cbName);  
                  retcode = SQLBindCol(hstmt, 3, SQL_C_WCHAR, szPhone, PHONE_LEN, &cbPhone);   
  
                  // Fetch and print each row of data. On an error, display a message and exit.  
                  for (int i=0 ; ; i++) {  
                     retcode = SQLFetch(hstmt);  
                     if (retcode == SQL_ERROR || retcode == SQL_SUCCESS_WITH_INFO)  
                        show_error();  
                     if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)  
                     {
                        //replace wprintf with printf
                        //%S with %ls
                        //warning C4477: 'wprintf' : format string '%S' requires an argument of type 'char *'
                        //but variadic argument 2 has type 'SQLWCHAR *'
                        //wprintf(L"%d: %S %S %S\n", i + 1, sCustID, szName, szPhone);  
                        printf("%d: %ls %ls %ls\n", i + 1, sCustID, szName, szPhone);  
                    }    
                     else  
                        break;  
                  }  
               }  
  
               // Process data  
               if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
                  SQLCancel(hstmt);  
                  SQLFreeHandle(SQL_HANDLE_STMT, hstmt);  
               }  
  
               SQLDisconnect(hdbc);  
            }  
  
            SQLFreeHandle(SQL_HANDLE_DBC, hdbc);  
         }  
      }  
      SQLFreeHandle(SQL_HANDLE_ENV, henv);  
   }  
}  

Consultez également Exemple de programme ODBC.

Pour obtenir des informations sur Consultez
Retour d’informations sur une colonne dans un jeu de résultats Fonction SQLDescribeCol
Extraction d’un bloc de données ou défilement d’un jeu de résultats Fonction SQLFetchScroll
Extraction de plusieurs lignes de données SQLFetch, fonction
Libération des mémoires tampons de colonne sur l’instruction Fonction SQLFreeStmt
Extraction d’une partie ou de la totalité d’une colonne de données Fonction SQLGetData
Retour du nombre de colonnes de jeu de résultats Fonction SQLNumResultCols

Voir aussi

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