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 :

Firedac, TLocalSQL et mise à jour Firebird


Sujet :

Bases de données Delphi

  1. #1
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 385
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 385
    Points : 2 999
    Points
    2 999
    Par défaut Firedac, TLocalSQL et mise à jour Firebird
    Bonjour

    Je suis toujours dans mon transfert de données Firebird.
    Mon export est bon et mon import se termine. Enfin ..... presque

    J'ai 6 tables source et donc 6 tables destination à mettre à jour.
    Par mettre à jour, j'entends sélectionner certains éléments d'une table source pour remplacer certaines lignes existantes (donc un upadte).
    Je m'explique pour une seule table mais le principe sera identique pour chacune.

    La table receveuse possède par exemple 50 lignes pour une entité (disons un client pour faire simple).
    La table donneuse possède aussi 50 lignes pour le même client mais seul les 10 premières sont à utiliser (ou les 10 suivantes, etc)

    Solution basique: J'ouvre la table donneuse avec un TFDQuery pour n'avoir que les lignes concernées et je boucle sur l'ensemble pour mettre les valeurs à la ligne correspondante dans la receveuse. Rien de plus classique.

    Solution imaginée mais jamais testée: Une seule requête update :
    update table receveuse inner join donneuse on ...

    Mais ce genre de requête sur deux bases différentes, pas possible.

    Ou alors, Est-ce que le TLocalSQL pourrait m'aider dans ce cas?

    A votre avis ? Ou quelqu'un aurait déjà fait ça ?

    Je ne demande pas le codage , juste savoir si c'est possible plutôt que d'y passer des heures pour arriver à un échec et repasser à la solution plus longue mais plus simple.

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 449
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 449
    Points : 24 856
    Points
    24 856
    Par défaut
    Pour avoir fait des migrations avec des centaines de tables, avec un nombre et des structures différentes entre la source et l'original, je te conseille de différer tes transformations
    Il y a bien dix ans, largement, j'ai utilisé DataPump, Talend et des scripts maisons, tout ce qui permet d'arriver à l'objectif

    En général, je commence par un schéma d'import temporaire qui est le miroir exact de la source, juste pour passer d'un SGBD A vers un SGBD B, aucune transformation en dehors des contraintes techniques

    Une fois cela, tout est fait à base de INSERT INTO dest.table ... SELECT FROM tmp.table ... sur depuis la base temporaire vers la base de destination, avec les recodages de base (genre thésaurus, changement d'unité, changement de type de colonne, concaténation ou répartition ...), en plus le SELECT peut soit réduire ou augmenter le nombre de ligne si la structure de jointure est différente, un GROUP BY pour réduire, un INNER ou CROSS JOIN par exemple si l'on passe d'une cardinalité 1-n dans la source vers une n-n dans la destination
    Ensuite, avec les UPDATE font les corrections plus complexes (longue à calculer par exemple)

    je pense que ton traitement par lot, client par client, c'est pour une table détail, par exemple reconstruire une jointure via des ID ... qui avec INSERT INTO dest.tabledetail ... SELECT FROM tmp.tabledetail INNER JOIN tmp.tablemaitre ... avec la clause d'unicité de l'ancien modèle de donnée permettant de trouver la relation dans le nouveau modèle, évidemment cela demande que les données maitres soient insérées avant, en général, mon ordre c'est Thésaurus, Maitre, Detail, Sous-Detail, ... selon un arbre de dépendance
    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

  3. #3
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 385
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 385
    Points : 2 999
    Points
    2 999
    Par défaut
    Je crois que je me suis mal expliqué.

    Le problème posé est le suivant:

    Un utilisateur doit traiter des données importées depuis un fichier style XML (pas tout à fait mais ça y ressemble).
    Ces données sont intégrées dans la base Firebird dans 5 tables différentes.
    Le traitement consiste à qualifier certains éléments avec différents flags pour un traitement ultérieur.

    Parfois, les données sont assez conséquentes et il faut pouvoir partager le travail mais pour des raisons techniques, dans un premier temps, chacun travaille sur son propre fichier.

    L'utilisateur principal va donc demander à 3 assistants de prendre chacun une partie des données à traiter.
    Chacun d'eux va importer le même fichier XML sur sa propre base locale et traiter une partie des données.
    Ensuite, chacun envoie une fichier fdb contenant les tables qu'il a traitées.
    On a donc un fichier fdb avec une structure identique aux 3 autres mais sans les flags modifiés.

    L'utilisateur principal va sélectionner le premier fichier et demander à récupérer les données traitées dans le premier.
    Puis pareil pour le second et le troisième.

    Je peux donc mettre à jour le fichier principal avec une partie des données à chaque fois.

    Fichier principal:
    A, 0
    B, 0
    C, 0

    Fichier secondaire 1
    A, 1
    B, 0
    C, 0

    Résultat dans Fichier principal
    A, 1
    B, 0
    C, 0

    Fichier secondaire 2
    A, 0
    B, 3
    C, 0

    Résultat dans Fichier principal
    A, 1
    B, 3
    C, 0

    etc.

    Avec le TLocalSQL, je sais que je peux utiliser des dataset de différents TFDConnection pour faire un select.
    Ce que je ne sais pas, c'est si je peux aussi faire un update de table1 sur connection1 à partir de table2 sur connection2 avec un inner join.
    Parce que dans ce cas, le traitement consistera en une seule requête pour chaque table au lieu de parcourir chaque enregistrement.

    En plus il ne faut pas oublier que le TFDLocalSQL utilise le moteur SQLite.
    Et là, je ne sais comment ça se passe.

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 449
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 449
    Points : 24 856
    Points
    24 856
    Par défaut
    FireDAC, je ne peux pas répondre mais sinon mon explication reste valide

    Tu injectes dans trois 'bases*' FireBird le contenu brut des trois source SQLite, une sorte de sas, un tampon
    Puis tu fais ta conciliation de données entre l'original et l'un des trois imports, puis le suivant et le dernier via des SQL FireBird, tu oublies le support initial.

    *trois bases, ou cinq tables temporaires permanentes dans une même base recyclé à chaque import,
    ou trois ensemble de cinq tables temporaires volatiles dans une même base avec un prefixe pour différencier chaque groupe d'import,
    j'utilise souvent les tables Temporaires dont le contenu n'existe que durant la transaction courante, après le commit, c'est tout vide, tu peux ainsi enchainer plusieurs fichiers consécutivement dans le même espace de travail
    les temporaires permanentes sont créés initialement et peuvent être conservées
    les temporaires volatiles sont créés dynamiquement et sont à supprimer en fin de traitement

    Si les données sont bien cloisonnées et qu'il n'y a de potentiel conflit entre les sources, peu importe l'ordre d'import, un seul jeu de table temporaire suffit
    Si les données peuvent se contredire, sans parler de la stratégie de conciliation qui peut être pénible, là, il te faut autant de jeux de tables temporaire qu'il y a de sources pour déterminer quelle donnée est la bonne (le truc basique de la date, si celle est fiable en terme de fuseau via un serveur de temps)

    Pour avoir eu en DBase, (oui oui, un projet qui a connu Clipper FoxPro, Delphi 5 à Delphi XE au moins et MySQL 5), il y a avait le même de concentration de données de bureau (5000 petits bureaux partout dans le monde, certains avec du courant avec un groupe électrogène) envoyant leurs données par tous moyens disponible, un concentrateur par pays, puis monde, des Flags (plutôt N°révision) aussi pour effectuer les patchs de données ... je ne sais plus si c'est ce système qui utilisait des GUID pour s'y retrouver entre les données locales et les données concentrées, sachant qu'il me semble que le local pouvait recevoir lui aussi des mise à jour à partir des concentrées, je te laisse imaginer les problématiques de savoir qui a raison à un instant T.
    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

  5. #5
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 036
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 036
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    Solution basique: J'ouvre la table donneuse avec un TFDQuery pour n'avoir que les lignes concernées et je boucle sur l'ensemble pour mettre les valeurs à la ligne correspondante dans la receveuse. Rien de plus classique.
    Je ne comprends pas pourquoi tu n'utilises pas FDBatchMove !

    Solution imaginée mais jamais testée: Une seule requête update :
    update table receveuse inner join donneuse on ...
    Déjà je ne suis pas sûr que cela fonctionne au sein d'une même base !
    Un UPDATE OR INSERT par contre ...
    genre UPDATE OR INSERT INTO TableReceveuse(colonnes) values SELECT colonnes from tablesource MATCHING(idunique)fonctionnerait peut-être au sein d'une même BDD Firebird
    Seulement voilà avec un LocalSQL il s'agit de SQLite donc l'instruction serait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    INSERT OR REPLACE INTO tablereceveuse(colonnes) VALUES SELECT colonnes from tablesource;
    J'ai de gros doutes quant à cette possiblité


    Ta principale contrainte serait de mettre dans tes tables distribuées un indicateur de modification en plus.

    Exemple : ta table Firebird clients (idClient,nom ..... )
    ta table SQlite clients (idClient,nom, .....,indic=0)
    après modification ou autre manipulation indic<>0 (tu peux ainsi gérer des modifications =1 , insert=2 , delete=3)
    le batchmove consistera en une requête (sans l'indic) sur la base SQlite récupérée select idclient,nom,... from clients where indic in (1,2)
    Pour le delete par contre je ne sais pas trop. Le batchmove n'est pas possible du moins je crois, le TLocalSQL est possible (quoique j'ai toujours des difficultés avec ce truc est interessant) une sorte de
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    DELETE FROM CLIENTSBASE WHERE idClient in (SELECT idclient from ClientsSQlite where indic=3)
    est, peut-être possible (ClientsBase,clientsSQLite sont les noms donnés dans le TlocalSQL) j'émets moins de doutes mais quand même certains

    Un utilisateur doit traiter des données importées depuis un fichier style XML (pas tout à fait mais ça y ressemble).
    j'aurais choisi du JSON plus à la mode
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

Discussions similaires

  1. Firebird 2.5.2 et 2.1.5, mise à jour de sécurité
    Par Ph. B. dans le forum Firebird
    Réponses: 0
    Dernier message: 24/04/2013, 13h58
  2. Mise à jour de Firebird sous Mac Os X - Lion
    Par CortelliStefano dans le forum Installation
    Réponses: 4
    Dernier message: 19/11/2012, 22h44
  3. [Delphi+Firebird] Erreur de mise à jour
    Par jojo86 dans le forum Bases de données
    Réponses: 18
    Dernier message: 02/03/2008, 11h36
  4. [FireBird 1.5]Mise à jour d'une SGBD ?
    Par Sitting Bull dans le forum Débuter
    Réponses: 3
    Dernier message: 03/09/2004, 16h45

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