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 :

[ADO] Faire abstraction du SGBD


Sujet :

Bases de données Delphi

  1. #1
    Membre du Club Avatar de Kephuro
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    61
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Calvados (Basse Normandie)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 61
    Points : 48
    Points
    48
    Par défaut [ADO] Faire abstraction du SGBD
    Bonjour à tous !

    Je suis en train de développer une petite application permettant de transférer certaines données (choisies) d'une table source vers une table destination.

    Le truc c'est que la nature de la source de données (Excel, Access, Oracle, Mysql...) et la destination ne doivent pas avoir d'importance (c'est le but de l'appli en fait).

    Pour la petite histoire : Je suis encore étudiant en informatique (BTS IG) et lors de mon stage de 2ème année qui s'est terminé il y a peu, on m'a demandé dans le cadre d'un développement de travailler avec des fichiers Excel. Les gars voulaient utiliser access pour stocker des infos et j'ai dû coder un petit truc permettant de transférer certaines données (toutes n'étaient pas importantes/pertinentes) du fichier excel vers Access.
    Je connaissais pas trop tout ce p'tite monde là, OLE, ADO, ODBC...mais je me suis quand même rendu compte qu'à mon avis on pouvait "simplement" faire bien plus que du Excel vers Access, mais potentiellement du n'importe quoi vers n'importe quoi pour peu qu'on dispose du driver ODBC.
    Je me trompe sûrement dans l'utilisation de certains termes, le sujet est particulièrement complexe pour un non-initié (et même pour les initiés, j'en suis sûr ), aussi ne m'en tenez pas trop rigueur



    Pour l'instant ça fonctionne bien avec Excel et Access mais j'ai des difficultés pour utiliser d'autres SGBD (même si je ne pense pas qu'Excel et Access soient des SGBD ?).

    Je ne maitrise pas vraiment les composants ADO et j'étais donc plutôt sur des générations de requêtes style INSERT INTO pour transférer les données.
    Le souci c'est que les requêtes qui fonctionnent sur l'un ne fonctionneront pas spécialement sur l'autre (essayez les crochets [ ] sur une requête vers MySQL il enverra bouler, alors que pour Excel et Access c'est nécessaire).

    Mon but c'est de coder le moins de "rustines" possible et de faire quelque chose d'assez générique, fonctionnant sur un maximum de SGBD différents, et pas faire un truc genre "Si Excel alors machin, si Mysql alors bidule..."...etc...chose que je commençais à faire avec les requêtes SQL.

    Et au final je me demande si j'ai bien retenu la bonne solution. Est-il possible d'utiliser les composants ADO et notamment les DataSet (pas encore trop familiarisé avec les termes et les fonctionnalités de chacun, mais ça viendra) pour simplifier le travail ?

    Ou alors est-ce que le plus simple pour faire du "générique" c'est d'utiliser les requêtes SQL ?



    Merci d'avance pour vos avis et conseils

  2. #2
    Membre chevronné

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

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Euh sans vouloir être cassant je pense que c'est une problématique qui existe depuis longtemps et que si quelqu'un avait déjà une solution miracle générique et bien tout le monde l'utiliserais.

    En ce sens pour moi c'est déjà quasiment le cas puisqu'avec ADO on peut se connecter quasiment à toutes les base de données avec un moyen uniforme (chaîne de connexion). Par contre l'utilisation en elle-même reste spécifique à la base de donnée. Normalement le média unique devrait être le langage SQL ce qui est plus ou moins le cas en général (bien qu'il y ait des fois des divergences d'implémentation comme les fameux [] d'Access/SQL Server). En fait ce sont justement ces divergences qui donnent une certaine identité à chaque SGBD(R?) sinon finalement on aurait qu'un seul moteur unique qui s'appellerait SGBD et puis c'est tout non ?
    Et je ne parles pas des fonctions systèmes, des routines qu'on a dans l'un et pas dans l'autre, etc...

    Bref pour que ADO fonctionne il faut à priori que le SGBD implémente un pilote. Je ne sais pas si cela implique des fonctions d'ajout/modification/suppression (autrement que de passer par du SQL) et si c'est ce genre de chose qui est utilisé par les composants genre ADOTable où c'est le composant qui gère les modification sur la table...
    Pour moi s'il devait y avoir une façon portable de faire les interactions cela devrait être du SQL. Mais là encore même si une majorité est respectée, des divergences apparaîssent. Donc faire un code full générique sans if Access if Oracle if MySql if SQLServer, ben honnêtement je vois pas.
    La FAQ - les Tutoriels - Le guide du développeur Delphi devant un problème

    Pas de sollicitations techniques par MP -

  3. #3
    Membre du Club Avatar de Kephuro
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    61
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Calvados (Basse Normandie)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 61
    Points : 48
    Points
    48
    Par défaut
    Euh sans vouloir être cassant je pense que c'est une problématique qui existe depuis longtemps et que si quelqu'un avait déjà une solution miracle générique et bien tout le monde l'utiliserais.
    Je sais bien ! Je n'ai pas non plus l'intention de coder la solution miracle, juste un truc qui soit compatible avec un maximum de choses. Si c'est compatible qu'avec 3 SGBD, m'en fiche.

    Mais tu as bien répondu à ma question, je pense qu'utiliser le SQL est le meilleur moyen, celui sur lequel théoriquement il y a le moins possible de "rustines" à faire. Je n'utilise pas les fonctionnalités avancées de chaque SGBD, juste celles de base pour de la lecture et de l'insertion de données.

    D'après ce que j'ai pu lire, les composants ADO génèrent de toutes façons du SQL et ça me semble logique qu'ils adaptent leur syntaxe pour un SGBD, c'est pour celà que je me demandais s'il n'était pas plus simple d'utiliser ce système là. Mais du coup, il semblerait que ce soit le curseur (ou moteur de curseur, j'ai pas bien rentenu) qui soit plus ou moins spécifique à chaque SGBD, ce qui déplace juste le problème au lieu de le régler.

  4. #4
    Membre chevronné

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

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Kephuro Voir le message
    D'après ce que j'ai pu lire, les composants ADO génèrent de toutes façons du SQL et ça me semble logique qu'ils adaptent leur syntaxe pour un SGBD, c'est pour celà que je me demandais s'il n'était pas plus simple d'utiliser ce système là. Mais du coup, il semblerait que ce soit le curseur (ou moteur de curseur, j'ai pas bien rentenu) qui soit plus ou moins spécifique à chaque SGBD, ce qui déplace juste le problème au lieu de le régler.
    C'est pour cela que je disais que chaque SGBD implémente un pilote pour que ADO fonctionne. Comme pour les cartes graphique, le pilote d'un SGBD se charge de faire la correspondance entre ce que l'on veut faire et comment on fait avec la mécanique du SGBD.
    La première des fonctionnalité à implémenter est bien sûr établir une connexion (et la fermer aussi) mais aussi envoyer une requête SQL, demander à démarrer une transaction et aussi à renvoyer des curseurs donc. Un curseur (je ne sais pas si tu es familier du terme en PL/SQL) c'est tout simplement un objet qui contient les lignes retournées par ta requête et que l'on peut parcourir (en avant, en arrière, premier, dernier, localiser). Tient ça te rappelle rien ? Ha ben c'est ce bon vieux DataSet. Le DataSet en lui-même est une surcouche du curseur quelque part. Quand tu demandes un first il transmet l'instruction first au curseur via le pilote donc.

    Dès lors on peut très bien imaginé qu'il est aussi prévu que les pilotes sachent faire les insertion/modification/suppression pour une table sans que les paramètre transmis soit du code SQL. Et c'est ce genre de fonctionnalité des pilotes qui est utilisée par les composant ADOTable par exemple pour transmettre à la base de donnée quand un enregistrement est ajouté, modifié ou supprimé.

    Néanmoins pour moi le moyen le plus universellement connu ça reste quand même le SQL en lui-même, même si quelques différences peuvent apparaître, hélas.
    La FAQ - les Tutoriels - Le guide du développeur Delphi devant un problème

    Pas de sollicitations techniques par MP -

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Personnellement, j'ai utilisé Borland DataPump pour faire une migration Paradox vers Oracle, alors déjà on commence par des soucis ce type avec les blobs, puis finalement, on se rend compte, que certaines données sont corrompues ...

    au final, j'ai fait un programme qui lit les tables paradox et génère du SQL pour remplir ces tables ... avec du SQL bien spécifique à paradox car je dois gérer des Dates ...

    Tiens, pour te donner une idée du defi, regarde les produits (leur propre Data Pump) de SQL Manager, tu verras, à quoi tu t'attaques, c'est très interressant, ...

    Sinon, des notions de polymorphismes (constructeurs et méthodes virtuelles, référence de classe, ...), cela vous parle, c'est l'une des clés pour écrire un moteur générique pouvant selon la source et la cible utiliser un objet différent ...

    tient ce sujet "Retrouver une instance de classe par son nom", je donne quelques idées pour utiliser le polymorphisme ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  6. #6
    Membre chevronné

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

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    En effet le polymorphisme est une bonne solution pour s'éviter des if à rallonge. Dès lors le seul et unique if qui existe c'est au début pour créer la classe qui va bien selon la base de donnée source/cible.
    La FAQ - les Tutoriels - Le guide du développeur Delphi devant un problème

    Pas de sollicitations techniques par MP -

  7. #7
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    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
    Points : 4 170
    Points
    4 170
    Par défaut
    Euh sans vouloir être cassant je pense que c'est une problématique qui existe depuis longtemps et que si quelqu'un avait déjà une solution miracle générique et bien tout le monde l'utiliserais.
    Justement ce genre de solution existe. Par exemple DTS et SSIS sont de petites merveilles en la matière (ou n'importe quel autre outil de type ETL). Ces outils sont fournis avec SQL Server. On peut être tenté de croire que ça ne marche qu'avec SQL Server mais en réalité on peut injecter n'importe quelle source de données vers n'importe quelle cible (à peu de choses près).

    Je l'utilise souvent d'ailleurs pour injecter des fichiers EXCEL dans Oracle. Ca fonctionne, on peut transformer les données au passage, et en plus ça tourne à la vitesse grand V.
    La seule restriction c'est qu'il faut trouver les bons drivers pour chaque SGBD (et que la solution n'est pas vraiment gratuite...).

    Sinon pour en revenir à ADO, ce type de traitement est parfaitement faisable. Il suffit de travailler avec les composants TADOTable.
    Un code du genre ci-dessous doit faire l'affaire :

    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
     
    Source.Open;
    Dest.Open;
    while not source.eof do
    begin
      Dest.Append;
      for i := 0 to Source.Fields.Count-1 do
      begin
        Dest.Fields[i].Value := Source.Fields[i].Value;
      end;
      Dest.Post;
      Source.Next;
    end;
    Dest.Close;
    Source.Close;
    ADO (plus exactement, le provider OLEDB définit dans la chaîne de connexion) se chargera alors de générer les bonnes requêtes SQL dans le dialecte du SGBD cible.

    Cependant, je ne préconiserais pas ce genre de solution pour une raison très simple : Les performances.

    Si on essaie de charger une table de cette manière, on pourra insérer quelques centaines de lignes par secondes.
    Hors avec un Bulkload, on serait beaucoup plus rapide (de l'ordre de 10000 l/s par exemple).
    Cependant, les bulkload se font généralement avec des API spécifiques à chaque SGBD (DirectPath pour Oracle, DTS pour SQL Server...).

    Aussi dans la pratique pour ce type de problème (en dehors d'un cas d'école), il vaut généralement mieux utiliser une solution spécifique au problème rencontré.

Discussions similaires

  1. existe t'il un moyen sous .net pour faire l'abstraction des SGBD
    Par Sfaxiano dans le forum Accès aux données
    Réponses: 2
    Dernier message: 30/07/2009, 18h07
  2. [ADO] faire une Update avec un recordset
    Par maniolo dans le forum VB 6 et antérieur
    Réponses: 12
    Dernier message: 21/08/2006, 22h18
  3. [SGBD][ADO] Utilisation des composants ADO
    Par Teb dans le forum Delphi .NET
    Réponses: 2
    Dernier message: 22/08/2005, 15h33
  4. [SGBD][ADO] et composants ADO.NET (bug)
    Par Harry dans le forum Delphi .NET
    Réponses: 2
    Dernier message: 25/04/2005, 09h20
  5. Application utilisable avec plusieurs SGBD - ADO ou DBX ?
    Par RamDevTeam dans le forum Bases de données
    Réponses: 5
    Dernier message: 30/12/2004, 08h25

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