Partager via


Extraction des données de résultat

Une application ODBC offre trois options pour l'extraction des données de résultat.

La première option est fondée sur SQLBindCol. Avant d'extraire le jeu de résultats, l'application utilise SQLBindCol pour lier chaque colonne du jeu de résultats à une variable de programme. Une fois les colonnes liées, le pilote transfère les données de la ligne actuelle vers les variables liées aux colonnes du jeu de résultats chaque fois que l'application appelle SQLFetch ou SQLFetchScroll. Le pilote gère les conversions de données si la colonne du jeu de résultats et la variable de programme possèdent des types de données différents. Si l'application possède une valeur SQL_ATTR_ROW_ARRAY_SIZE supérieure à 1, elle peut lier les colonnes de résultat à des tableaux de variables qui seront tous remplis lors de chaque appel à SQLFetchScroll.

La deuxième option est basée sur SQLGetData. L'application n'utilise pas SQLBindCol pour lier des colonnes de jeu de résultats aux variables de programme. Après chaque appel à SQLFetch, l'application appelle une fois SQLGetData pour chaque colonne au sein du jeu de résultats. SQLGetData demande au pilote de transférer les données d'une colonne spécifique du jeu de résultats vers une variable de programme spécifique et précise les types de données de la colonne et de la variable. Le pilote peut ainsi convertir des données si la colonne de résultat et la variable de programme possèdent des types de données différents. Les colonnes Text, ntext et image sont généralement trop volumineuses pour tenir dans une variable de programme mais peuvent néanmoins être extraites à l'aide de la fonction SQLGetData. Si les données text, ntext ou image dans la colonne de résultat sont plus importantes que la variable de programme, SQLGetData retourne SQL_SUCCESS_WITH_INFO et SQLSTATE 01004 (chaîne de données tronquée à droite). Les appels successifs à SQLGetData retournent des segments successifs des données text ou image. Une fois la fin des données atteinte, SQLGetData retourne SQL_SUCCESS. Chaque extraction retourne un jeu de lignes, ou « ensemble de lignes », si SQL_ATTR_ROW_ARRAY_SIZE est supérieur à 1. Avant d'utiliser SQLGetData, vous devez d'abord utiliser la fonction SQLSetPos pour spécifier une ligne spécifique dans l'ensemble de lignes en tant que ligne actuelle.

La troisième option est d'utiliser un mélange des fonctions SQLBindCol et SQLGetData. Par exemple, une application peut lier les dix premières colonnes d'un jeu de résultats, puis lors de chaque extraction, appeler trois fois SQLGetData pour extraire les données de trois colonnes indépendantes. Cette approche est généralement employée lorsqu'un jeu de résultats contient une ou plusieurs colonnes text ou image.

En fonction des options de curseur définies pour le jeu de résultats, une application peut également utiliser les options de défilement de SQLFetchScroll pour faire défiler le jeu de résultats.

Toute utilisation à outrance de SQLBindCol dans le but de lier une colonne de jeu de résultats à une variable de programme est coûteuse puisque SQLBindCol entraîne une allocation de mémoire par un pilote ODBC. Lorsque vous liez une colonne de résultat à une variable, cette liaison demeure en vigueur jusqu'à ce que vous appeliez SQLFreeHandle pour libérer le descripteur d'instruction ou appeliez SQLFreeStmt avec fOption défini sur SQL_UNBIND. Les liaisons ne sont pas automatiquement annulées à la fin de l'instruction.

Cette logique vous permet de gérer avec efficacité l'exécution à maintes reprises de la même instruction avec des paramètres différents. Du fait que le jeu de résultats conserve la même structure, vous pouvez lier le jeu de résultats une fois, traiter toutes les instructions SELECT, puis appeler la fonction SQLFreeStmt avec fOption défini sur SQL_UNBIND après la dernière exécution. N'appelez pas SQLBindCol pour lier les colonnes dans un jeu de résultats sans appeler avant tout SQLFreeStmt avec fOption défini sur SQL_UNBIND pour libérer toutes les liaisons précédentes.

Lorsque vous utilisez la fonction SQLBindCol, vous pouvez procéder à une liaison selon les lignes ou selon les colonnes. La liaison selon les lignes est un tantinet plus rapide que la liaison selon les colonnes.

Vous pouvez vous servir de la fonction SQLGetData pour extraire des données colonne par colonne au lieu de lier les colonnes d'un jeu de résultats à l'aide de SQLBindCol. Si un jeu de résultats contient uniquement quelques lignes, l'utilisation de SQLGetData à la place de SQLBindCol s'avèrera plus rapide ; sinon, SQLBindCol offre de meilleures performances. Si vous n'insérez pas toujours les données dans le même jeu de variables, il est préférable d'utiliser la fonction SQLGetData plutôt que de procéder constamment à de nouvelles liaisons. Vous pouvez utiliser uniquement la fonction SQLGetData dans les colonnes qui figurent dans la liste de sélection après avoir lié toutes les colonnes avec SQLBindCol. La colonne doit également apparaître après toutes les colonnes dans lesquelles vous avez déjà utilisé SQLGetData.

Les fonctions ODBC qui gèrent le déplacement des données à l'intérieur et en dehors des variables de programme, notamment SQLGetData, SQLBindCol et SQLBindParameter, prennent en charge la conversion de types de données implicite. Par exemple, si une application lie une colonne d'entiers à une variable de programme de chaîne de caractères, le pilote convertit automatiquement les données d'entier en caractère avant de les insérer dans la variable de programme.

La conversion de données dans les applications doit être réduite. À moins que la conversion de données ne soit nécessaire pour le traitement pris en charge par l'application, les applications doivent lier les colonnes et les paramètres à des variables de programme du même type de données. En revanche, si les données doivent être converties d'un type à un autre, il est plus efficace de confier la conversion au pilote plutôt que de l'effectuer dans l'application. Normalement, le pilote ODBC SQL Server Native Client se contente de transférer directement les données des tampons réseau vers les variables de l'application. En confiant la conversion des données au pilote, vous forcez ce dernier à mettre les données en mémoire tampon et à les convertir au moyen de cycles processeur.

Les variables de programme doivent avoir une taille suffisamment importante pour contenir des données transférées à partir d'une colonne, à l'exception des données text, ntext et image. Si une application tente d'extraire les données d'un jeu de résultats et de les placer dans une variable trop petite pour les contenir, le pilote émet un avertissement. Cette opération contraint le pilote à allouer de la mémoire pour le message et le pilote et l'application doivent tous les deux utiliser des cycles processeur pour traiter le message et gérer les erreurs. L'application doit soit allouer une variable suffisamment grande pour accueillir les données extraites, soit faire appel à la fonction SUBSTRING dans la liste de sélection pour réduire la taille de la colonne au sein du jeu de résultats.

Soyez vigilant lorsque vous utilisez SQL_C_DEFAULT pour définir le type de la variable C. SQL_C_DEFAULT spécifie que le type de la variable C correspond au type de données SQL de la colonne ou du paramètre. Si vous spécifiez SQL_C_DEFAULT pour une colonne ntext, nchar ou nvarchar, les données Unicode sont retournées à l'application. Ceci peut entraîner divers problèmes si l'application n'a pas été codée pour gérer des données Unicode. Les mêmes types de problèmes peuvent survenir avec le type de données uniqueidentifier (SQL_GUID).

Les données text, ntext et image sont généralement trop volumineuses pour tenir dans une seule variable de programme et sont traditionnellement traitées avec la fonction SQLGetData et non la fonction SQLBindCol. Lors de l'utilisation de curseurs côté serveur, le pilote ODBC SQL Server Native Client est optimisé pour ne pas transmettre les données des colonnes indépendantes text, ntext ou image au moment où la ligne est extraite. Les données de type text, ntext ou image ne sont pas réellement extraites du serveur tant que l'application n'a pas émis SQLGetData pour la colonne.

Cette optimisation peut être appliquée à des applications afin qu'aucune donnée text, ntext ou image ne s'affiche pendant qu'un utilisateur fait défiler le curseur de haut en bas. Après que l'utilisateur a sélectionné une ligne, l'application peut appeler SQLGetData pour extraire les données text, ntext ou image. Ceci évite de transmettre les données text, ntext ou image pour toutes les lignes non sélectionnées par l'utilisateur et peut ainsi empêcher la transmission de quantités très importantes de données.

Voir aussi

Concepts