IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Accéder à une base de données ODBC avec une édition Personnelle de Delphi

Ce tutoriel propose aux possesseurs de Delphi Edition Personnelle l'accès aux données d'une base relationnelle via les API ODBC. Pour ce faire, nous utiliserons une traduction en Delphi des bibliothèques sql.h livrées par Microsoft.

Article lu   fois.

L'auteur

Profil Pro

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Informations générales

I-A. Introduction

Depuis Delphi 6, Borland met à disposition des versions gratuites de son outil de développement « Delphi ». Ces versions sont nommées « éditions personnelles ». Cela permet de réaliser et de distribuer, dans le cadre stipulé dans la licence d'utilisation des éditions personnelles, des applications sans avoir à investir dans un outil.

Même si ces versions sont gratuites, elles contiennent suffisamment pour réaliser un grand nombre d'applications. La partie faisant souvent défaut est l'accès aux bases de données, car aucun composant n'est fourni dans une édition personnelle.

Ce manque peut être comblé de diverses manières, par l'ajout de composants tiers, par utilisation d'API fournies avec la base de données ou bien alors par connexion ODBC.

Pour les possesseurs des versions 6 et 7 de Delphi, vous pouvez également accéder à des bases de données en utilisant les bibliothèques de types ADO. Pour cette technique, vous pouvez vous reporter à l'article écrit par Thierry AIM. Cette technique n'est malheureusement pas applicable à Delphi 2005, car il ne permet malheureusement pas l'importation de bibliothèques de types.

Nous allons donc voir la manière d'utiliser Delphi pour accéder aux bases de données via les fonctions API de l'ODBC.
Une fois ce tutoriel parcouru, vous pourrez consulter la documentation des fonctions ODBC pour une utilisation plus approfondie.

I-B. Qu'est-ce que l'ODBC ?

L'ODBC (Open DataBase Connectivity) est une couche logicielle (Middleware) de Windows permettant à un programme d'accéder à des bases de données. Pour que cela fonctionne, la base de données doit fournir un pilote compatible ODBC afin de traduire les ordres SQL du programme en ordres compréhensibles par la base de données utilisée.

Les postes Windows disposent souvent d'un minimum de pilotes fournis par Microsoft qui contiennent entre autres un pilote pour Access, permettant ainsi d'interagir avec ce type de bases sans pour autant disposer du logiciel Access complet.

Ces pilotes sont distribués au travers du MDAC, qui est livré en standard avec Windows XP. Pour télécharger les dernières versions, direction le site de Microsoft.

I-C. Documentation ODBC

Pour en savoir plus, vous pouvez consulter la documentation anglaise fournie par Microsoft dans son MSDN.

La liste et descriptions, en anglais, des fonctions ODBC sont disponibles ici.

I-D. Interface ODBC utilisée

Pour pouvoir utiliser les exemples qui seront donnés par la suite, vous devez utiliser une unité Delphi contenant toutes les définitions des fonctions et types utilisés par l'interface ODBC.

Pour cela, téléchargez l'archive ZIP suivante qui contient l'unité « iodbc.pas » que vous n'aurez qu'à inclure dans la clause uses de votre projet.

Cette unité a été réalisée en se basant sur la version 3.51 de l'ODBC.

II. Paramétrage de la source ODBC

Il existe deux méthodes pour se connecter à une source ODBC. La première à l'aide du gestionnaire de sources ODBC de Windows (manuellement ou par programmation), la seconde en indiquant le nom et l'emplacement de la base de données.

II-A. Accès au gestionnaire de sources ODBC (manuel)

Sous Windows XP, vous pouvez accéder à ce gestionnaire via le « Panneau de configuration », ensuite dans « Outils d'administration » puis l'icône « Sources de données (ODBC) ».

À partir de là, vous pouvez ajouter une nouvelle source à l'aide du bouton « Ajouter ».

L'écran suivant est important, car c'est ici que vous allez définir quel pilote vous souhaitez utiliser (Access, dBase, etc.). La liste présente vous donnera également le nom exact du driver à utiliser pour les méthodes de connexion par programmation.

II-B. Paramétrage du gestionnaire de sources ODBC par programmation

Plutôt que de réinventer la roue, vous pouvez consulter la FAQ Delphi et plus particulièrement l'article rédigé par Bloon « Comment créer une source ODBC par programme ? ».

III. Connexion à une source ODBC

Pour manipuler vos données, vous devez d'abord établir une connexion à votre base.

La première chose à faire est de demander un accès au gestionnaire ODBC par la réservation d'un handle d'environnement et de tester si la demande a été autorisée ou pas :

 
Sélectionnez
var
// Variables pour la connexion ODBC
    hEnv: SQLHENV;
    RetCode: SQLRETURN;
begin
// Allocation d'un Handle d'environnement
    RetCode := SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, Henv);
    if SQLSucceeded(retcode) then
    // OK
    Else
    // Échec

On déclare donc une variable hEnv de type SQLHENV. Cette variable sera ensuite utilisée pour réaliser une connexion à une source de données.

Pour tester si l'allocation a été réalisée ou pas, on déclare également une variable RetCode de type SQLRETURN. Cette variable sera testée à l'aide de la fonction SQLSucceeded() qui retourne True ou False selon le cas.

Pour réserver notre handle d'environnement, nous utilisons la fonction SQLAllocHandle() en lui fournissant trois paramètres :

  • SQL_HANDLE_ENV : le type de handle que l'on souhaite ;
  • SQL_NULL_HANDLE : notre handle ne dépend pas d'un handle 'parent' ;
  • hEnv : notre variable.

Si la connexion au gestionnaire ODBC s'est bien réalisée, nous devons lui indiquer dans quelle version majeure de l'ODBC nous voulons travailler :

 
Sélectionnez
// Fixe la version de l'ODBC
    RetCode := SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, SQLPOINTER(SQL_OV_ODBC3), 0);
    if SQLSucceeded(retcode) then
    // OK
    Else
    // Échec

La fonction SQLSetEnvAttr() permet de réaliser cette opération en nous retournant toujours le résultat dans notre variable RetCode. Une erreur peut survenir si, par exemple, l'utilisateur utilise une version 2 de l'ODBC alors que nous souhaitons travailler en version 3.

Le premier paramètre passé est notre handle d'environnement, suivi de variables indiquant notre paramétrage. Pour plus d'informations sur cette fonction, reportez-vous à la documentation MSDN.

Pour réaliser la connexion à notre base de données, nous devons à nouveau utiliser SQLAllocHandle() pour réserver, cette fois, un handle de connexion :

 
Sélectionnez
var
// Variables pour la connexion ODBC
    ...
    hDbc: SQLHDBC;
    ...
begin
    ...
// Allocation d'un Handle de connexion
    RetCode := SQLAllocHandle(SQL_HANDLE_DBC, hEnv, HDbc);
    if sqlsucceeded(retcode) then
    begin
    // OK
    Else
    // Échec d'allocation du handle de connexion

On déclare une variable hdbc de type SQLHDBC puis nous appelons la fonction avec les trois paramètres suivants :

  • SQL_HANDLE_DBC : le type de handle que l'on souhaite réserver ;
  • hEnv : le handle d'environnement réservé précédemment ;
  • hDbc : notre variable.

Si vous accédez à plusieurs bases de données, vous pouvez créer plusieurs handle de connexion (hDbc1, hDbc2, etc.) en utilisant le même handle d'environnement (hEnv).

Vient ensuite le moment tant attendu, la connexion à notre base de données :

1re méthode : en utilisant le gestionnaire de sources ODBC :

 
Sélectionnez
// Se connecte à la source ODBC 'NorthWind' 
    RetCode := SQLConnect(hDbc, pchar('NorthWind'), SQL_NTS,  
               pchar('sa'), SQL_NTS, pchar(''), SQL_NTS);
    if sqlsucceeded(retcode) then
    // OK
    Else
    // Échec de connexion

La fonction SQLConnect() attend les paramètres suivants :

  • HDbc : notre handle de connexion ;
  • Pchar('') : le nom de notre source de données ODBC ;
  • SQL_NTS ;
  • Pchar('') : le nom d'utilisateur de notre base de données ;
  • SQL_NTS ;
  • Pchar('') : le mot de passe de l'utilisateur ;
  • SQL_NTS.

2e méthode : en indiquant directement le nom de la base :

 
Sélectionnez
Var
    ...
    sChaine : String;
    iChaine_Len : Integer;
    siRet : smallInt;
begin     
    ...
// Se connecte à la base "bd1.mdb" en utilisant le driver ACCESS
    iChaine_Len := 256;
    sChaine := StringOfChar(' ',iChaine_Len);
    RetCode := SQLDriverConnect(hDbc, Application.Handle,
               pchar('DRIVER=Microsoft Access Driver (*.mdb); DBQ=' +
               ExtractFilePath(Application.ExeName)+ 'bd1.mdb'),
               SQL_NTS, PChar(sChaine), iChaine_Len, siRet,              
               SQL_DRIVER_NOPROMPT);
    if sqlsucceeded(retcode) then
    // OK
    Else
    // Échec

Cette méthode est un peu plus complexe que la précédente, mais évite un paramétrage du gestionnaire ODBC.

En premier, nous déclarons trois variables sChaine, iChaine_Len et siRet. Nous affectons à iChaine_Len la valeur 256 qui correspondra à la longueur maximale de la chaine de caractères stockée dans sChaine. Ensuite, nous initialisons sChaine avec des espaces pour y effacer les caractères parasites (StringOfChar()).

L'appel de la fonction SQLDriverConnect() se fait avec les paramètres suivants :

  • HDbc : notre handle de connexion ;
  • Application.handle : handle Windows de notre programme ;
  • Pchar('') : chaine de connexion (voir plus bas) ;
  • SQL_NTS ;
  • Pchar(sChaine) : notre variable sChaine qui recevra la chaine de connexion complète en cas de réussite ;
  • iChaine_Len : longueur maximale initialisée pour notre variable sChaine ;
  • siRet : variable qui contiendra la longueur de la chaine retournée dans sChaine ;
  • SQL_DRIVER_NOPROMPT : pas de fenêtre de connexion si les paramètres sont suffisants pour se connecter à la base de données.

La chaine de connexion contient les paramètres nécessaires pour que le gestionnaire ODBC puisse réaliser correctement la connexion. Il faut indiquer au minimum « DRIVER=[Nom du driver ODBC];DBQ=[Nom de la base de données] ». D'autres paramètres peuvent être ajoutés, comme le nom d'utilisateur, le mot de passe, etc. Reportez-vous à la documentation MSDN pour plus d'informations.

La variable sChaine contiendra, en cas de succès, la chaine de connexion complète. C'est-à-dire les arguments que nous avons passés (DRIVER et DBQ) plus les paramètres par défaut valables pour le type de pilote choisi.

Et voilà, nous venons de réaliser entièrement notre connexion à une base de données !

IV. Préparation et exécution d'une requête SQL

Lire et écrire dans une base de données s'effectue en utilisant des requêtes SQL qui sont envoyées au gestionnaire ODBC qui va les traduire, à l'aide du pilote, dans le langage de la base de données.

Comme exemple de base de données, nous allons faire simple en imaginant une table nommée « Employes » qui contient uniquement deux champs « Prenom » et « Nom » de type texte pour y stocker les noms du personnel d'une société.

Tout d'abord, réservons un traditionnel handle qui sera cette fois un handle de résultat (statement en anglais) :

 
Sélectionnez
var
// Variables pour la connexion ODBC
    ...
    hStmt: SQLSTMT;
    ...
begin
    ...
// Allocation d'un Handle de résultat
    RetCode := SQLAllocHandle(SQL_HANDLE_STMT, hDbc, hStmt);
    if sqlsucceeded(retcode) then
    begin
    // OK
    Else
    // Échec d'allocation du handle de résultat

On déclare une variable hStmt de type SQLHSTMT puis nous appelons la fonction avec les trois paramètres suivants :

  • SQL_HANDLE_STMT : le type de handle que l'on souhaite réserver ;
  • hDbc : le handle de connexion réservé précédemment ;
  • hStmt : notre variable.

Chaque handle de résultat permet d'exécuter une requête SQL et, le cas échéant, d'en extraire le résultat.

Si vous avez besoin d'exécuter plusieurs requêtes en même temps, vous pouvez créer plusieurs handle de résultat (hStmt1, hStmt2, etc.) en utilisant le même handle de connexion (hDbc).

Une fois notre handle réservé, nous pouvons envoyer notre requête à la base de données :

 
Sélectionnez
var
    ...
    sSQL : String;
begin     
    ...
// Requête SQL à exécuter
    sSQL := 'Select * from Employes order by Nom';
// Lance la requête
    RetCode := SQLExecDirect(hStmt, Pchar(sSQL), SQL_NTS);
    if sqlsucceeded(retcode) then
    // OK
    Else
    // Échec de la requête SQL

Pour plus de clarté dans le code, la requête SQL sera stockée dans une variable nommée sSQL de type String.

L'exécution d'une requête s'effectue à l'aide de la fonction SQLExecDirect() qui a besoin des paramètres suivants :

  • hStmt : le handle de résultat réservé pour cette requête ;
  • pChar(sSQL) : texte de la requête à exécuter ;
  • SQL_NTS.

Si la requête a pu être exécutée par la base de données, SQLSucceeded() retourna True.

V. Lecture des données d'une requête SQL « Select »

La requête Select précédente nous retourne un jeu d'enregistrements avec le prénom et le nom des employés, classé par le Nom.

Nous afficherons dans un contrôle TListBox le contenu de la 2e colonne (Nom) pour tous les employés :

 
Sélectionnez
Var
    ...
    sChaine : String;
    iChaine_Len : Integer;
    iRet : Integer;
begin     
    ...
    iChaine_Len := 50 ;
    sChaine := StringOfChar(' ',iChaine_Len);
// Traite tous les enregistrements 1 à 1
    while (SQLSucceeded(SQLFetch(hstmt))) do
    begin
    // Retourne la 2e colonne
        SQLGetData(hstmt, 2, SQL_C_CHAR, PChar(sChaine), iChaine_Len, iRet);
    // Ajoute le résultat au contrôle TListBox     
        ListBox.Items.Append(Copy(sChaine, 1, iRet));
    end ; 
// libère le handle de résultat réservé
    SQLFreeHandle(SQL_HANDLE_STMT, hStmt);

Nous allons avoir besoin des variables suivantes :

  • sChaine pour lire le contenu du champ Nom ;
  • iChaine_Len pour indiquer la longueur de texte maximale à lire ;
  • iRet pour savoir combien de caractères ont été lus et retournés dans sChaine.

Dans notre base, le nom ne peut excéder 50 caractères, nous affectons donc 50 à iChaine_Len puis initialisons sChaine avec autant d'espaces.

Lorsqu'une requête Select est exécutée, elle ne se positionne sur aucun enregistrement. Pour faire défiler les enregistrements, il faut utiliser la fonction SQLFetch() qui retourne une valeur pouvant être traitée par SQLSucceeded() et qui indique True si un enregistrement a été lu ou False dans le cas contraire (pas d'enregistrement retourné ou dernier enregistrement dépassé). SQLFetch() n'attend qu'un seul paramètre : le handle de résultat (hStmt).

Une fois notre enregistrement lu, il faut extraire la colonne (champ) qui nous intéresse, on utilise pour ça la fonction SQLGetData() qui attend en paramètres :

  • hStmt : le handle de résultat de notre requête Select ;
  • x : le N de la colonne qui nous intéresse (à partir de 1) ;
  • SQL_C_CHAR : le type de valeur lue (ici il s'agit de texte) ;
  • Pchar(sChaine) : la variable devant recevoir le résultat ;
  • iChaine_Len : la longueur maximale à retourner (Nb de caractères pour du texte) ;
  • iRet : variable qui contiendra le nombre de caractères réellement lus.

Il ne nous reste plus qu'à extraire de sChaine le nombre de caractères lus à l'aide de l'instruction copy().

Nous n'avons plus qu'à répéter ces instructions tant que SQLFetch() s'exécute correctement pour parcourir tous les enregistrements retournés par notre requête Select.

Une fois l'opération terminée, il ne nous reste plus qu'à libérer le handle de résultat réservé à l'aide de l'instruction SQLFreeHandle() (voir plus bas l'utilisation de cette fonction).

VI. Utilisation de données binaires

L'utilisation de requêtes SQL permet de réaliser la plupart des opérations nécessaires pour manipuler les données d'une base. Cependant, vous ne pourrez pas bâtir une requête si vous souhaitez, par exemple, stocker une image dans un champ binaire (blob ou OLE sous Access).

VI-A. Écriture dans la base

Pour ce faire, il faut utiliser une requête SQL qui attend un paramètre externe. Ce dernier lui sera passé à l'aide d'un pointeur afin que le driver ODBC puisse retrouver les données à stocker.

Comme exemple, nous allons mettre à jour une table « employes » en copiant le contenu d'un composant image dans le champ «photo» d'un enregistrement. La requête à utiliser sera donc la suivante :

 
Sélectionnez
Update Employes set Photo = ? where lastname = 'Dupond'

ODBC va attendre un paramètre à l'endroit où se situe le point d'interrogation.

 
Sélectionnez
var
    ...
    sChaine : String;
    iChaine_Len : Integer;
    iRet : Integer;
    imgStream: tmemorystream;
    iLenStream: integer;
    pStream: Pointer;begin
begin
    ...
    RetCode := SQLPrepare(hstmt, PChar('Update Employes set Photo = ? 
where lastname = ''Dupond'''), SQL_NTS);
    Try
        imgstream := TMemoryStream.Create;
        image1.Picture.Bitmap.SaveToStream(imgStream);
        iLenStream := imgstream.Size;
        pStream := imgstream.Memory;
        RetCode := SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, iLenStream, 0, pStream, 0, iLenStream);
        if sqlsucceeded(retcode) then
        begin
            RetCode := SQLExecute(hstmt);
            if not sqlsucceeded(retcode) then
                raise ESQLerror.CreateDiag(SQL_HANDLE_STMT, hstmt, RetCode);
        end
        else
            raise ESQLerror.CreateDiag(SQL_HANDLE_STMT, hstmt, RetCode);
        end;
    Finally
        imgstream.Free;
    end;
end;

Nous devons d'abord indiquer à la base de données que nous allons utiliser une requête avec paramètre. Pour ce faire, nous utilisons la fonction SQLPrepare() en lui passant en paramètres le handle de la requête (hStmt), la requête SQL avec un zéro terminal (pChar()) puis SQL_NTS.

Ensuite, nous définissons ce qui doit être copié (image1.Picture.Bitmap) et à quel endroit ODBC devra aller récupérer ces données (imgStream.Memory).

Après, nous appelons la fonction SQLBindParameter() en lui passant en paramètres :

  • hStmt : le handle de résultat réservé pour cette requête ;
  • x : le numéro du paramètre que nous passons, à partir de 1 (notre requête peut contenir plusieurs paramètres) ;
  • SQL_PARAM_INPUT ;
  • SQL_C_BINARY ;
  • SQL_LONGVARBINARY ;
  • iLenStream : la longueur des données à transmettre ;
  • ;
  • pStream : l'adresse du début des données à lire ;
  • ;
  • iLenStream : à nouveau la longueur des données.

Une fois le paramètre attaché à notre requête SQL, nous pouvons l'exécuter à l'aide de SQLExecute() qui n'attend que le handle de la requête préparée (hStmt).

VI-B. Lecture des données

Une fois les données stockées, il faut pouvoir les relire !

 
Sélectionnez
var
  ...
  sRetour: array[0..64000] of char;
  iRet:    integer;
  RetCode: SQLReturn;
  msSteam: tMemoryStream;
begin
  ...
  msStream := tMemoryStream.Create;
  repeat
    RetCode := SQLGetData(hstmt, 1, SQL_C_BINARY, @sRetour[0],
      sizeof(sRetour), iRet);
    if (SQLSucceeded(RetCode)) and (iRet > 0) then
      msStream.WriteBuffer(sRetour, min(iRet, sizeof(sRetour)));
  until RetCode <> SQL_SUCCESS_WITH_INFO;
  msStream.seek(0, soFromBeginning);
  image1.Picture.Bitmap.LoadFromStream(msStream);
end;

Nous allons utiliser la fonction SQLGetData() vue plus haut en lui passant comme 3e paramètre la constante SQL_C_BINARY pour lui indiquer que nous souhaitons lire des données binaires.

Dans l'exemple, nous utilisons un buffer de 64 000 octets, mais cela ne nous empêche pas de lire plus de données. SQLGetData() nous retournera comme valeur SQL_SUCCESS_WITH_INFO tant qu'il restera des données à lire. Un nouvel appel à SQLGetData() permettra d'obtenir les informations suivantes. Une boucle Repeat // Until RetCode <> SQL_SUCCESS_WITH_INFO nous permettra donc de gérer la lecture quelle que soit la longueur des données à retourner.

Une fois les données stockées dans notre buffer sRetour, nous les envoyons vers un flux mémoire (msStream) afin de pouvoir les transmettre à notre composant image à l'aide de image1.Picture.Bitmap.LoadFromStream().

VII. Déconnexion d'une source ODBC

Une fois que vous avez fini de travailler sur une source de données, il faut se déconnecter à l'aide de l'instruction SQLDisconnect() qui n'attend comme paramètre que le handle de connexion (hDbc) :

 
Sélectionnez
SQLDisconnect(hDbc) ;

Ce n'est qu'une fois la source déconnectée que vous pourrez libérer le handle de connexion.

VIII. Libération des handles réservés

Une fois qu'un handle n'est plus utile, il faut le libérer à l'aide de l'instruction SQLFreeHandle() qui attend deux paramètres : le type de handle et le handle lui-même.

Dans l'ordre de libération, nous avons donc :

 
Sélectionnez
SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);

IX. Gestion des erreurs

Si un code d'erreur est retourné (SQLSucceeded() retourne False) vous pouvez générer une exception à l'aide de l'instruction ESQLerror.CreateDiag() qui a besoin des paramètres Type de handle, handle et numéro d'erreur :

 
Sélectionnez
ESQLerror.CreateDiag(SQL_HANDLE_STMT, hStmt, RetCode)
ESQLerror.CreateDiag(SQL_HANDLE_DBC, hDbc, RetCode)
ESQLerror.CreateDiag(SQL_HANDLE_ENV, hEnv, RetCode)

X. Fonctions de lecture de données simplifiées

Les informations décrites dans ce chapitre sont provisoires. Des composants seront bientôt disponibles afin de manipuler encore plus facilement des bases de données via ODBC.

La fonction SQLGetData() n'est pas très pratique à utiliser pour extraire autre chose que du texte, et même dans ce cas cela impose plusieurs lignes de code. Pour vous simplifier la vie, l'archive ZIP contient une unité nommée « codbc.pas » qui contient les fonctions suivantes :

 
Sélectionnez
SQLGetFloat(hstmt: SQLHSTMT; const iColonne: Integer; var fValeur: Extended): SQLReturn;

SQLGetString(hstmt: SQLHSTMT; const iColonne: Integer; var Chaine: string): SQLReturn;

SQLGetInteger(hstmt: SQLHSTMT; const iColonne: Integer; var iValeur: Integer): SQLReturn;

SQLGetBoolean(hstmt: SQLHSTMT; const iColonne: Integer; var bValeur: Boolean): SQLReturn;

SQLGetStringDate(hstmt: SQLHSTMT; const iColonne: Integer; var Chaine: string): SQLReturn;

Chaque fonction attend le même nombre de paramètres. Les deux premiers sont le handle de résultat (hStmt) et le N de la colonne (champ) à lire. Le 3e paramètre est la variable devant contenir le résultat et qui est donc de type différent pour chaque fonction.

Pour les données binaires, deux fonctions existent :

 
Sélectionnez
SQLSendStreamToParam(hstmt: SQLHSTMT; const iParam: integer; var msStream: tMemoryStream; var iLength : SQLLEN): SQLReturn;

SQLGetStream(hstmt: SQLHSTMT; const iColonne: integer; var msStream: tMemoryStream): SQLReturn;

La 1re permet d'affecter un flux tMemoryStream comme paramètre d'une requête SQL en lui fournissant en paramètre le flux et la longueur de ce dernier.

La seconde permet de lire des données binaires et de stocker le résultat dans un flux mémoire initialisé préalablement. Une fois le flux constitué, un appel de tMemoryStream.seek(0, soFromBeginning) est réalisé pour positionner le flux à son début automatiquement.

Cette unité contient également la fonction suivante qui permet de charger un tStringList avec toutes les valeurs d'une colonne (de type texte) pour un jeu de résultat complet :

 
Sélectionnez
SQLGetStrings(hstmt: SQLHSTMT; const iColonne: Integer; var Liste: TStringList): SQLReturn;

Nous aurions donc pu utiliser cette fonction dans notre exemple de lecture de requête Select au lieu de la boucle While…

XI. Noms et types des champs

Les informations décrites dans ce chapitre sont provisoires. Des composants seront bientôt disponibles afin de manipuler encore plus facilement des bases de données via ODBC.

L'unité codbc.pas contient également trois fonctions afin de vous simplifier la vie pour lister le nom des colonnes d'une table ou d'une requête, ainsi que de connaître le type de chaque colonne :

 
Sélectionnez
SQLGetColumnsName(hdbc: SQLHDBC; const sTable: string; var Liste: TStringList): SQLReturn;

Vous permet de stocker dans un tStringList le nom de toutes les colonnes d'une table. La fonction attend les paramètres : handle de connexion (hDbc), nom de la table et la variable tStringList devant recevoir le résultat.

 
Sélectionnez
SQLGetSQLColumnsName(hdbc: SQLHDBC; const sSQL: string; var Liste: TStringList): SQLReturn;

Même fonction que SQLGetColumsName(), mais pour le résultat d'une requête au lieu d'une table. Il faut donc lui fournir le texte de la requête à la place du nom de la table.

 
Sélectionnez
SQLGetColumnsTypeName(hdbc: SQLHDBC; const sTable: string; var Liste: TStringList): SQLReturn;

Cette dernière fonction vous retourne le type de chaque champ d'une table dans un tStringList. Les paramètres à indiquer sont : handle de connexion (hDbc), nom de la table et la variable tStringList devant recevoir le résultat.

XII. Remerciements

Giovanny Temgoua, Thierry Aim, Laurent Dardenne pour leurs remarques, suggestions, motivation ;-), etc.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

Copyright © 2006 Michaël Duval. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.