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

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Bases de données Delphi Discussion :

[Tutoriel]Utiliser OLEDB en Delphi


Sujet :

Bases de données Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé

    Avatar de Nono40
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2002
    Messages
    8 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2002
    Messages : 8 640
    Par défaut [Tutoriel]Utiliser OLEDB en Delphi
    Bonjour à tous

    Franck Soriano nous propose un nouveau tutoriel qui vous fera découvrir l'utilistation d'OLEDB avec des applications Delphi

    Cet article présente comment utiliser directement OLEDB pour exécuter une requête sur une base de données. SQL Server est utilisé pour les exemples, mais ce tutoriel peut s'appliquer à n'importe quel SGBD.
    Grâce à OLEDB et la classe TMemoryDataSet présentée dans l'article précédent, on peut obtenir des performances quatre fois supérieures qu'avec une application ADO traditionnelle ou dbExpress.
    C'est article est le troisième de la série sur l'Optimisation des accès aux bases de données dont les deux premiers chapitres sont ici :
    I : Comparatif des API d'accès aux bases de données disponibles avec Delphi
    II : Développer un DataSet en mémoire
    Delphi :
    La F.A.Q. , 877 réponses à vos questions !
    264 sources à consulter/télécharger !

  2. #2
    Membre émérite Avatar de chaplin
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 215
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 215
    Par défaut
    J'ai pris le soin de lire l'article en entier. Il est dans la tradition des autres articles, clair comme de l'eau de roche.

    Dois je comprendre que ADO.NET est le successeur de OLEDB sur .NET ?

  3. #3
    Membre Expert

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Par défaut
    Merci.

    On peut voir les choses comme ça. Cependant, OLEDB est toujours utilisable à travers ADO.NET.

    ADO.NET est plus performant que OLEDB (en tout cas avec SQL Server) tout en restant très simple d'utilisation, avec un modèle de programmation semblable à ADO.

    En un mot, c'est la simplicité d'utilisation de ADO avec des performances encore meilleures que OLEDB.

  4. #4
    Membre émérite Avatar de chaplin
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 215
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 215
    Par défaut
    Avec du code managé, on arrive à de meilleures performances qu'avec du code natif .

    EDIT:

    J'ai fait une recherche rapide sur google et j'ai trouvé ce lien:

    http://www.google.fr/search?hl=fr&q=...vs+oledb&meta=

    Que faut-il comprendre ?

  5. #5
    Membre Expert

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Par défaut
    Il ne faut pas croire que le code managé est plus lent que du Win32.

    D'abord, lorsque tu installe le framework .Net, la première chose que fait l'installer en fin d'install c'est lancer la compilation des images natives des assembly .Net.
    Donc au final, lorsque ton appli appelle ADO.NET, elle appelle du code natif, compilé spécifiquement pour ton architecture technique en utilisant toutes les optimisations possibles que tu n'aurais pas avec une compil générique pour tous les processeurs compatibles.

    Ensuite, les allocations mémoires avec le GC sont instantanées ce qui est loin d'être le cas avec la mémoire COM... Sans parler du fait que le traitement de collecte de la mémoire est déporté à un moment où la machine est moins chargée et exécuté dans un thread distinct, en tâche de fond.

    Ainsi, au final une appli .NET peut parfaitement être plus rapide qu'une appli Win32.

    Il y a quelques temps, j'avais fait un bench pour comparer les perfs en lecture d'ADO.NET et OleDb. Je précise encore une fois : avec SQL Server.

    De plus il ne faut pas perdre de vu que le provider ADO.NET pour SQL Server fait parti intégrante du Framework. Tu peux aussi passer par un provider OleDb, mais dans ce cas tu ajoutes une couche supplémentaire.
    Et bien sûr, la couche du dessus ne pourra pas être plus rapide que la couche du dessous sur laquelle elle s'appuie.

  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    737
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 737

  7. #7
    Membre averti
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2006
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2006
    Messages : 41
    Par défaut
    Merci pour le tutorial

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2006
    Messages : 3
    Par défaut Profiter des performances en Delphi7
    Bonjour,

    Je me suis arrêté à Delphi7, mais j'aimerais évidemment pouvoir utiliser les résultats obtenus par Franck Soriano dans des applications basées sur SQL Server ou Access. Est-ce possible d'obtenir cela?
    Merci beaucoup.

    Josse Franken.

  9. #9
    Membre Expert

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Billets dans le blog
    1
    Par défaut
    L'exemple de Franck Soriano est déjà valable pour SQL Server, ensuite pour les autres bases il suffit de récupérer le GUID de leur provider OLEDB respectif et de les utiliser en lieu et place de celui de SQL Server.

    Et la version de Delphi n'est pas très importante pour parvenir au même résultat (sauf s'il y a des boucles for...in mais qui peuvent être adaptées de toutes façons).

  10. #10
    Membre Expert

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Par défaut
    J'ai écrit le code avec D2006 mais c'est du pareil au même avec D7.

    Il faudra peut-être faire quelques ajustement mineurs pour pouvoir compiler mon source avec D7 mais en soit, il ne devrait rien y avoir de bien bloquant (évidemment je n'ai pas testé). Il est même fort possible que le code compile directement en D7. Je ne me souviens pas avoir utilisé de nouveautés particulières du langage.

    Ensuite pour utiliser Access, il devrait suffir de choisir MS Jet 4 comme provider OLEDB, en passant par une chaîne de connexion, de la même façon que dans l'exemple pour ouvrir un fichier Excel...

  11. #11
    Nouveau candidat au Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 2
    Par défaut P'tit complément
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
     
    {$APPTYPE CONSOLE}
     
    uses
      Windows,
      Classes,
      DB, ADODB, AdoInt, ActiveX, ComObj, OleDB,
      SysUtils;
     
    type TCGUID = class
        GUID: TGUID;
        constructor Create( Input: String);
      end;
     
    constructor TCGUID.Create(Input: String);
    begin
      GUID := StringToGUID( Input);
    end;
     
    function CreateADOObject(const ClassID: TGUID): IUnknown;
    var Status: HResult;
        FPUControlWord: Word;
    begin
      asm
        FNSTCW FPUControlWord
      end;
      Status := CoCreateInstance( ClassID, nil, CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER, IUnknown, Result);
      asm
        FNCLEX
        FLDCW FPUControlWord
      end;
      OleCheck(Status);
    end;
     
    procedure GetProviderNames(Names: TStrings);
    var
      RSCon: ADORecordsetConstruction;
      Rowset: IRowset;
      SourcesRowset: ISourcesRowset;
      SourcesRecordset: _Recordset;
      SourcesName, SourcesType, SourcesGUID: TField;
    begin
      SourcesRecordset := CreateADOObject(CLASS_Recordset) as _Recordset;
      RSCon := SourcesRecordset as ADORecordsetConstruction;
      SourcesRowset := CreateComObject(CLSID_OLEDB_ENUMERATOR) as ISourcesRowset;
      OleCheck(SourcesRowset.GetSourcesRowset(nil, IRowset, 0, nil, IUnknown(Rowset)));
      RSCon.Rowset := RowSet;
      with TADODataSet.Create(nil) do
      try
        Recordset := SourcesRecordset;
        First;
        SourcesName := FieldByName('SOURCES_NAME');      { do not localize }
        SourcesGUID := FieldByName('SOURCES_PARSENAME'); { do not localize }
        SourcesType := FieldByName('SOURCES_TYPE');      { do not localize }
        Names.BeginUpdate;
        try
          while not EOF do
          begin
            if SourcesType.AsInteger = DBSOURCETYPE_DATASOURCE then
              Names.AddObject( SourcesName.AsString, TCGUID.Create( SourcesGUID.AsString));
            Next;
          end;
        finally
          Names.EndUpdate;
        end;
      finally
        Free;
      end;
    end;
     
    const FranckSorianoExampleGUID : TGUID = '{0C7FF16C-38E3-11d0-97AB-00C04FC2AD98}';
     
    var SL: TStringList;
        Id: Integer;
     
    begin
      CoInitializeEx( nil, COINIT_MULTITHREADED);
      try
        SL := TStringList.Create;
        try
          try
            GetProviderNames( SL);
            for Id := 0 to SL.Count - 1 do
              if IsEqualGUID( TCGUID( SL.Objects[ Id]).GUID, FranckSorianoExampleGUID) then
              begin
                MessageBox( 0, 'Trouvé', 'OLEDBProvidersEnum', MB_OK);
                Break;
              end;
          finally
            while SL.Count > 0 do
            begin
                SL.Objects[ 0].Destroy();
                SL.Objects[ 0] := nil;
                SL.Delete( 0);
            end;
          end;    
        finally
          SL.Destroy;
        end;  
      finally
        CoUninitialize;
      end;
    end.

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 8
    Par défaut Utilisation de OLE DB avec les procédures stockées
    Bonjour,

    je souhaite exécuter des procédures stockées sous SQL Server 2005 à partir de Delphi 2009. J'ai utilisé le tutoriel de Franck, que je remercie au passage pour la qualité du tuto, et j'ai un petit souci. Je peux faire des requêtes basique sans problème, appeler des procédures stockées qui retourne un dataset sans problème, mais dès que j'appelle un procédure stockée avec des paramètres INPUT ou OUTPUT, au moment du cmd.Execute, j'ai un message me disant que le paramètre @toto n'est pas défini.
    J'ai donc cherché dans la doc de Microsoft et j'ai vu que pour les paramètres, il faut appeler SetParameterInfo en remplissant des structures. J'ai donc essayé cette méthode mais sans succès.
    Peut-on utiliser le code de Franck directement sans modification pour appeler des procédures stockées AVEC paramètres ? Si oui je serais ravi de connaître la marche à suivre :-)
    Sinon, avez vous un exemple de code avec le code de Franck qui me montrerait comment appeler une procédure stockée avec paramètres ?
    Merci à tous et bonne fin de journée.

  13. #13
    Membre Expert

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Par défaut
    Je n'ai jamais chercher à exécuter de procédures stockées, par contre les requêtes paramétrées ne posent aucun problème.

    J'ai expliqué comment faire une requête paramétrée au II-E, et tu as un exemple d'utilisation au III-D.

    Le point important, c'est qu'il faut mettre un "?" dans la requête à la place du paramètre.

    Dès lors tu dois pouvoir exécuter une procédure stockée en jouant la requête :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    exec maprocedure ?, ?, ?

    Et si tu as un paramètre de sortie dans la SP :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    exec maprocedure ?, ?, ? output

    Par contre, de paramètres de type Date, il faut préciser la précision et le scale dans la définition du binding. Et j'ai un bug dans le passage des paramètres de type widestring. Il faut apporter quelques corrections à TOleDbParams.Create :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    constructor TOleDbParams.Create(Params: TParams; ACmd : ICommand; Cnt : TOleDbConnection);
    ...
          ftDateTime:
            begin
              ParamSize := 8;
              CheckSize(Offset + 8 + ParamSize);
              DateValue := Param.AsDateTime;
              move(DateValue, PData^.Data[0], ParamSize);
              Binding.wType := DBTYPE_DATE;
              Binding.bPrecision := 23;
              Binding.bScale := 3;
            end;
          ftWideString, ftWideMemo:
            begin
              widestringValue := Param.AsWideString;
              ParamSize := length(widestringValue)*2;
              Binding.cbMaxLen := ParamSize;
     
              CheckSize(Offset + 8 + ParamSize);
     
              PData^.LengthValue := length(widestringValue)*2;
              move(widestringValue[1], PData^.Data[0], ParamSize);
     
              Binding.wType := DBTYPE_WSTR;
            end;

Discussions similaires

  1. [Tutoriel] Utilisation de Delphi Prism
    Par Nono40 dans le forum EDI
    Réponses: 0
    Dernier message: 19/05/2009, 16h38
  2. [adabas] Quel tutoriel utiliser ?
    Par fmdr dans le forum Autres SGBD
    Réponses: 1
    Dernier message: 26/12/2006, 11h08
  3. Comment utiliser Word avec Delphi 7 ?
    Par muquet dans le forum Débuter
    Réponses: 9
    Dernier message: 06/12/2005, 18h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo