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 :

Copie d'une table mySQL vers une table SQLite : optimisation de code


Sujet :

Bases de données Delphi

  1. #1
    Invité
    Invité(e)
    Par défaut Copie d'une table mySQL vers une table SQLite : optimisation de code
    Bonjour,

    Avec FireDac, je copie une table mySQL lue à partir d'une chaîne de connexion mySQLConn->mySQLQuery posée sur la Form vers une base SQLite3:memory: définie par SQLiteModule->SQLiteConn ->SQLiteQuery (donc utilisant un DataModule). J'ai eu un petit peu de mal à gérer les NULL mais sinon l'ensemble est fonctionnel.

    Le code utilisé actuellement est le suivant.
    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
    with mySQLQuery do try
      with SQL do begin
        Clear;
        Add('SELECT elID, elCODE, elINSEE, elNOM, elPRENOM, elTEL,');
        Add('elADRESSE, elCP, elVILLE,  elCONTRAT, elPERMIS, elDATEPERMIS,');
        Add('elDATEANCIENNETE, elMEMO, xxACTIF, xxPOSTE, xxUSER, xxSTAMP');
        Add('FROM mysqlELV;');
      end;
      Open;
      if not isEmpty then begin
        First;
        while not(EOF) do begin
          inc(nGauge);
          sbGauge.Progress := nGauge;
           //---Enr .[Déb]
          with SQLiteModule.SQLiteQuery do try
            Close;
            with SQL do begin
              Clear;
              Add('INSERT INTO lisqlELV (');
              Add('elID, elCODE, elINSEE, elNOM, elPRENOM, elTEL, elADRESSE, elCP,');
              Add('elVILLE, elCONTRAT, elPERMIS, elDATEPERMIS, elDATEANCIENNETE, elMEMO,');
              Add('xxACTIF, xxPOSTE, xxUSER, xxSTAMP');
              Add(') VALUES (');
              Add(':paID, :paCODE, :paINSEE, :paNOM, :paPRENOM, :paTEL, :paADRESSE,');
              Add(':paCP, :paVILLE, :paCONTRAT, :paPERMIS, :paDATEPERMIS, :paDATEANCIENNETE,');
              Add(':paMEMO, :paACTIF, :paPOSTE, :paUSER, :paSTAMP');
              Add(');');
            end;
            with Params do begin
              ParamByName('paID').AsString              := mySQLQuery.Fields[0].AsString;
              ParamByName('paCODE').AsString            := mySQLQuery.Fields[1].AsString;
              ParamByName('paINSEE').AsString           := mySQLQuery.Fields[2].AsString;
              ParamByName('paNOM').AsString             := mySQLQuery.Fields[3].AsString;
              ParamByName('paPRENOM').AsString          := mySQLQuery.Fields[4].AsString;
              ParamByName('paTEL').AsString             := mySQLQuery.Fields[5].AsString;
              ParamByName('paADRESSE').AsString         := mySQLQuery.Fields[6].AsString;
              ParamByName('paCP').AsString              := mySQLQuery.Fields[7].AsString;
              ParamByName('paVILLE').AsString           := mySQLQuery.Fields[8].AsString;
              ParamByName('paCONTRAT').AsString         := mySQLQuery.Fields[9].AsString;
              ParamByName('paPERMIS').AsString          := mySQLQuery.Fields[10].AsString;
              ParamByName('paDATEPERMIS').AsString      := mySQLQuery.Fields[11].AsString;
              ParamByName('paDATEANCIENNETE').AsString  := mySQLQuery.Fields[12].AsString;
              ParamByName('paMEMO').AsString            := mySQLQuery.Fields[13].AsString;
              ParamByName('paACTIF').AsBoolean          := mySQLQuery.Fields[14].AsBoolean;
              ParamByName('paPOSTE').AsString           := mySQLQuery.Fields[15].AsString;
              ParamByName('paUSER').AsString            := mySQLQuery.Fields[16].AsString;
              ParamByName('paSTAMP').AsString           := mySQLQuery.Fields[17].AsString;
            end;
            ExecSQL;
            Close;
          except
            on E: EFDDBEngineException do
              ShowMessage(E.Errors[0].Message);
          end;
          //---Enr .[Fin]
          Next;
        end;
      end;
      Close;
      if mySQLConn.Connected then mySQLConn.Connected := False;
    except
      on E: EFDDBEngineException do
        ShowMessage(E.Errors[0].Message);
    end;
    J'espère que la méthode est appropriée. Ce n'est pas la plus rapide. J'aurais pu imaginer par exemple, une lecture de la table mySQL directement dans une TStringGrid, puis le transfert de la TStringGrid directement dans la table SQLite3 éventuellement en insérant toutes les lignes à la fois.
    Je n'ai pas retenu cette option
    • parce qu'il m'est difficile (impossible lors de la requète d'insertion multi-tuples) de faire progresser correctement une jauge (pour l'ergonomie)
    • et surtout parce que j'utilise des blobs images qui contiennent pratiquement toujours des caractères NULL disséminés dans les chaînes. Or je suppose que comme en Lazarus, les cellules des TStringGrids ne contiennent que des champs de type C (qui tronquent les chaînes à la rencontre du premier caractère NULL). Je n'ai pas vérifié en Delphi, mais en Lazarus, j'ai travaillé longtemps là-dessus pour conserver la persistance des images dans une TStringGrid.


    Donc j'ai décidé de parcourir ma table mySQL avec un SQLquery.Open et d'insérer les enregistrements lus dans la base SQLite3 un par un avec un SQLQuery.ExecSQL. Je pense que la méthode est classique.

    J'aimerais toutefois résoudre quelques petits problèmes "basés" sur ce code.

    Premièrement après l'Open:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    with mySQLQuery do 
      try 
        [...]
        Open;
        if isEmpty then begin
          Close; 
          Exit;
        end;
        First;
        [...]
      except
     
      end;
    Peut-on casser l'Open comme cela ? Je pense que oui... mais je n'ai pas osé non pas à cause du Close... je pense qu'il n'y a pas de problème à ce niveau-là mais à cause du try engagé... On peut quitter une exception par un Exit ? Hum...

    Deuxièmement (anecdotique) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    with SQLiteQuery do 
            Close;
    Je me demandais s'il était possible de savoir s'il n'était pas "close" ? Idiot de fermer quelque chose qu'il l'est déjà...
    Donc if <? (pas close)?> then Close;

    Troisièmement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    except
            on E: EFDDBEngineException do
              ShowMessage(E.Errors[0].Message);
     end;
    Très pratique quand on est en production [Run]... Mais en exploitation, pour l'utilisateur final, je voudrais plutôt un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    MessageDlg( 'La base interne est indisponible. ' +
                      'Le programme va s''arrêter.',
                      TMsgDlgType.mtError, [TMsgDlgBtn.mbOK], 0);
          Application.Terminate;
    Peut-on différencier les 2 cas ?

    Merci.
    Dernière modification par Invité ; 30/10/2014 à 11h53.

  2. #2
    Membre chevronné

    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 288
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Août 2002
    Messages : 1 288
    Points : 1 936
    Points
    1 936
    Par défaut
    Pour les deux premiers points, je ne connais pas FireDac.
    Pour le troisièment: les directives de compilation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      on E: EFDDBEngineException do begin
    {$IFDEF DEBUG}
    ShowMessage(E.Errors[0].Message);{$ELSE}
    MessageDlg( 'La base interne est indisponible. ' +
                      'Le programme va s''arrêter.',
                      TMsgDlgType.mtError, [TMsgDlgBtn.mbOK], 0);
          Application.Terminate;{$ENDIF}
    end;
    Delphi 7/XE2/XE3
    C#
    Oracle 9i à 12c
    SQL Server 2008 à 2014

  3. #3
    Invité
    Invité(e)
    Par défaut
    Adopté. Merci.

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    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 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut
    Bonjour Gilles, en vacances ?

    pour Firedac, il n'y aurait pas maintenant un FDBatchmove ? (n'existe pas en XE4) qui te permettrait de faire cela beaucoup plus vite
    http://docwiki.embarcadero.com/CodeE...tchMove_Sample

    es-tu obligé de faire une copie physique de la table ou une table en mémoire (TFDMemTable) ferait t-elle l'affaire ?
    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

  5. #5
    Invité
    Invité(e)
    Par défaut
    Bonjour Serge,

    Oui physiquement jusqu'à lundi inclus
    Non intellectuellement, mais FireDac c'est nouveau pour moi... J'en suis encore à comprendre "If so, then restart ADExplorer"... Je ne savais même pas ce que c'était que le ADExplorer. Pas cela sous Lazarus... Donc là j'ai défini ma connexion dans le FireDac Explorer pour pouvoir travailler sur ma dbGrid... et je regarde ton "truc" !
    Merci.
    Dernière modification par Invité ; 30/10/2014 à 15h19.

  6. #6
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    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 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut
    nos posts se sont croisés durant ma modification, interruption due à un coup de téléphone, donc je fais un petit UP (pas taper les modos)
    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

  7. #7
    Invité
    Invité(e)
    Par défaut
    Vu... mais c'est sensationnel ce "truc"... et les possibilités sont nombreuses. Je me contenterai des requêtes pour rester au plus proche de ce que je connais... Mais pfffff !
    Cela a l'air simple à mettre en oeuvre, à priori... Mais la doc sur FireDac ? Avant de commencer à râler, j'ai déjà trouvé cela http://www.embarcadero.com/fr/produc...studio/firedac (comme d'hab)... Mais les classes et les méthodes disponibles pour qu'un néophyte sur la question comme moi puisse en quelques instants s'apercevoir que cela existe et comment le mettre en oeuvre, c'est où ? Parce que d'après ce que je lis, cela pourrait simplifier mon code à plein d'endroits... Le progress est intégré... et la détection d'erreur aussi semble-t-il.

  8. #8
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    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 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut
    Sur ce que j'en sais , c'est inspiré de l'excellent Tbatchmove de la palette BDE , donc déjà cela donne des pistes de recherche .
    j'ai également compris qu'il y avait un exemple de code .
    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

  9. #9
    Invité
    Invité(e)
    Par défaut
    Désolé j'étais plongé dans ma lecture. Je suis arrivé avec 1 heure de retard chez des amateurs de C... Il faut de tout pour faire un monde... mais comme le dit l'interlocuteur dans le fil de sa discussion : "j'ai l'impression d'être dans une autre planète"

    Dans ma lecture, je cherchais comment on déclarait un index sur un TFBQuery... Par tâtonnements plus que par documentation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    mySQLQuery.AddIndex('col0_asc','elID','trim(elid)',[soNoCase]);
    mySQLQuery.AddIndex('col0_desc','elID','trim(elID)',[soNoCase, soDescending]);
    mySQLQuery.AddIndex('col1_asc','elCODE','trim(elCODE)',[soNoCase]);
    mySQLQuery.AddIndex('col1_desc','elCODE','trim(elCODE)',[soNoCase, soDescending]);  //[ixDescending]
    end;
    Certainement évident, mais cela fait longtemps... Le retour est difficile... Et compte tenu de cette possibilité, j'envisage de virer tous mes indexes de tables qui ne sont pas des clés primaires, uniques ou étrangères.
    Dernière modification par Invité ; 30/10/2014 à 16h47.

  10. #10
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    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 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    je ne connaissais pas cette histoire d'index sur les querys , j'ai donc passé un petit 1/4 d'heure pour faire un essai

    environnement Firebird + XE4 FMX

    j'ai d'abord posé tous mes composants
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        StringGrid1: TStringGrid;
        ADQuery1: TADQuery;
        ADConnection1: TADConnection;
        ADGUIxWaitCursor1: TADGUIxWaitCursor;
        ADPhysIBDriverLink1: TADPhysIBDriverLink;
    puis lié la Grid à la Query
    j'ai ensuite créé des indexs à la query en les ajoutant via l'IDE , la table n'ayant que 2 champs j'ai donc fait (selon ton shéma) 4 index
    CODEASC,CODEDESC,LIBELLEASC,LIBELLEDESC
    Quelques radiobuttons pour faire les test de changement d'index

    et un code selon chaque radiobuttons (j'aurais certainement pu simplifier)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (Sender as TRadioButton).IsChecked then  ADQuery1.IndexName:=<l'index selon le bouton>;
    là , chou blanc , royal planton du style objet inconnu

    le seul truc qui a fonctionné (ici le code en ordre descendant) je me suis inspiré de ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TForm4.CodeDescChange(Sender: TObject);
    begin
    ADQuery1.active:=false;
    if (Sender as TRadioButton).IsChecked then  ADQuery1.IndexFieldNames:='CODE_APPOSE:D';
    ADQuery1.active:=true;
    end;
    Questionnements :
    Est-ce que le SGBD à de l'importance ?
    Quelle différence avec une query avec la clause ORDER BY ?
    Peut-être est-ce pour un SQLLocal

    parlant du SQL local ne serait-ce pas une solution à exploiter dans ton contexte (le truc qui s'installerait sans dll de plus ? à vérifier)
    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

  11. #11
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Alors je reviens à la question initiale. Pour la sortie du try par un exit je ne sais toujours pas. Il faut un maître des arcanes : Paul, ShaileTroll ?

    Pour le close du SQLQuery, je suppose que l'on peut procéder ainsi.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    with aSQLQuery do
        if Active then Close;
    Pour le FDBBatchMove, comme pressenti cela fait fort...
    Je copie la structure (uniquement) d'une table mySQL hébergée aELV dans une autre table mySQL bELV.
    Sur la Form, je pose 3 objets en plus de mes chaînes de connexions pour les 2 tables : FDBatchMove1, FDBatchMoveDatasetReader1 et FDBatchMoveDataSetWriter1.
    Le reste se réduit à quelques lignes de codes :
    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
    {Les 2 requêtes sont affectées aux 2 queries 
     !! Pour les 2, il faut une requête de lecture : un SELECT y compris pour la cible, ici mySQLQueryB}
    with mySQLQueryA do begin
      if Active then Close;
         with SQL do begin
           Clear;
           Add('SELECT elID, elCODE, elINSEE, elNOM, elPRENOM, elTEL,');
           Add('elADRESSE, elCP, elVILLE,  elCONTRAT, elPERMIS, elDATEPERMIS,');
           Add('elDATEANCIENNETE, elMEMO, xxACTIF, xxPOSTE, xxUSER, xxSTAMP');
           Add('FROM aELV;');
        end;
    end;
     
    with mySQLQueryB  do begin
       if Active then Close;
       with SQL do begin
          Clear;
          Add('SELECT elID, elCODE, elINSEE, elNOM, elPRENOM, elTEL,');
          Add('elADRESSE, elCP, elVILLE,  elCONTRAT, elPERMIS, elDATEPERMIS,');
          Add('elDATEANCIENNETE, elMEMO, xxACTIF, xxPOSTE, xxUSER, xxSTAMP');
          Add('FROM bELV;');
        end;
    end;
     
    //Affectation de la source et de la cible au BatchMove
    with FDBatchMoveDataSetReader1 do 
      DataSet := mySQLQueryA
     
    with FDBatchMoveDataSetWriter1 do
      DataSet := mySQLQueryB;
     
     
    //Execution du BatchMove
    with FDBatchMove1 do 
      Execute;
    Pour suivre la progression
    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
     
    procedure TfLogin.FDBatchMove1Progress(ASender: TObject;
      APhase: TFDBatchMovePhase);
    begin
      if APhase in [psStarting] then
        with sbGauge do begin
          MinValue := 0;
          MaxValue := FDBatchMoveDataSetReader1.DataSet.RecordCount; {Nombre de lignes transférées}
          Progress := 0;
          if MaxValue > 0 
            then
              if not Visible then Visible := True
            else
              if Visible then Visible := False;
          Refresh;
        end;
     
      if APhase in [psProgress, psFinishing] then begin
         sbGauge.Progress := FDBatchMove1.InsertCount;
       end;
    end;
    Comme je disposais au départ de 43 enregistrements dans la la table aELV, j'ai modifié le StatisTicInterval à 10 (au lieu de 100) sinon le rafraîchissement du ProgressBar ne se fait pas... puisque tous les 100. L'ensemble est très rapide aussi bien à paramétrer qu'à l'exécution. Il existe un traitement onError. Maintenant, je cherche un moyen efficace de chaîner les BatchMoves de toutes les tables pour obtenir un ProgressBar global. Il y a déjà une solution simple. Un SELECT COUNT(*) sur les tables sources. Et on incrémente une variable cumulée pour le ProgressBar. Vraiment sensationnel, sauf la doc. Il a fallu que j'ouvre un .dfm - je n'en ai trouvé qu'un sur le net- pour découvrir que la requête cible était un SELECT. Sinon j'ai découvert plein de possibilités avec les tables dont je ne sais pas me servir. Cela doit faire rigoler Serge.

    PS :
    Initialement j'ai réussi le move de ma base mySQL hébergée vers ma base SQLite3:memory:... Mais visiblement, après modifications, j'ai un problème avec les NULL dans les BlobText enfin les TEXT de SQLite... Déjà rencontré. Je ne me souviens plus comment j'ai réglé le problème.
    Serge, je vais être obligé de quitter le SQLite :memory: le temps de voir avec une table en dur... Je pourrai alors gérer les indexes comme je le fais avec mySQL et te transmettre pour test. Je ne sais pas si c'est une impression mais dans l'ordre de prédilection, j'utilise pgSQL et mySQL et tous les souvenirs que j'ai de SQLite sont euh... "compliqués" .
    Dernière modification par Invité ; 31/10/2014 à 18h36.

  12. #12
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    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 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut
    Citation Envoyé par selzig Voir le message
    Alors je reviens à la question initiale. Pour la sortie du try par un exit je ne sais toujours pas. Il faut un maître des arcanes : Paul, ShaileTroll ?
    Pour le close du SQLQuery, je suppose que l'on peut procéder ainsi.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    with aSQLQuery do
        if Active then Close;
    si tu allais regarder le code du Close ;-)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure TDataSet.Close;
    begin
      Active := False;
    end;
    donc aSQLQuery.Active:=False tout simplement suffit

    Citation Envoyé par selzig Voir le message
    Cela doit faire rigoler Serge.
    exact
    Citation Envoyé par selzig Voir le message
    Mais visiblement, après modifications, j'ai un problème avec les NULL dans les BlobText en fin les TEXT de SQLite...
    ben un blobtest , par définition ça termine par un NULL (comme un chaine caractère) , un Blob Binary par contre ...
    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

  13. #13
    Invité
    Invité(e)
    Par défaut
    Bonjour Serge,

    Citation Envoyé par SergioMaster Voir le message
    si tu allais regarder le code du Close ;-)
    ben un blobtest , par définition ça termine par un NULL (comme un chaine caractère) , un Blob Binary par contre ...
    J'ai déjà du mal à trouver les éléments de doc, je ne vois pas où je prendrais le temps pour aller regarder les sources. Elles sont où d'ailleurs ? Remarque que dans tout le fatras qu'a installé Delphi, on peut supposer que quelque part, il y a des sources... Mais je croyais qu'on n'en disposait plus depuis la belle époque.

    Pour le NULL, la déclaration a aussi une fonction d'obligation de remplissage ou non, et également une gestion particulière au niveau des clés. J'ai l'impression, presque la certitude, que mySQL et SQLite ne traitent pas le problème de la même façon au niveau de l'obligation de remplissage. D'un autre côté, j'ai du mal à faire remonter certaines erreurs de SQLite au niveau des exceptions, mais c'était pareil en Lazarus... Je regarderai cela demain. Il faut que je retrouve mon utilitaire pour lire les bases SQLite. Il y a l'add-on Mozilla, mais j'ai (j'avais) un exe qui faisait cela très bien. Si cela me casse les pieds, je regarderai "tes tables-mémoire".
    Dernière modification par Invité ; 31/10/2014 à 18h37.

  14. #14
    Membre émérite
    Avatar de Thierry Laborde
    Homme Profil pro
    N/A
    Inscrit en
    Avril 2002
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : N/A

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 391
    Points : 2 529
    Points
    2 529
    Par défaut
    Bonjour,

    Citation Envoyé par selzig Voir le message
    je ne vois pas où je prendrais le temps pour aller regarder les sources. Elles sont où d'ailleurs ? Remarque que dans tout le fatras qu'a installé Delphi, on peut supposer que quelque part, il y a des sources...
    "Démarrer", "Tous les Programmes", "Embarcadero RAD Studio XE7", "Exemples" ....

    Et ensuite une fois qu'il ouvre le répertoire : "Object Pascal", "Database", "FireDAC"

  15. #15
    Membre émérite
    Avatar de Thierry Laborde
    Homme Profil pro
    N/A
    Inscrit en
    Avril 2002
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : N/A

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 391
    Points : 2 529
    Points
    2 529
    Par défaut
    Citation Envoyé par selzig Voir le message
    Il faut que je retrouve mon utilitaire pour lire les bases SQLite.
    L'explorateur de données est là pour ça, et fonctionne sur tous les types de bases de données supportés par FireDAC.

  16. #16
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    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 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut
    Bonjour,
    J'ai déjà du mal à trouver les éléments de doc, je ne vois pas où je prendrais le temps pour aller regarder les sources.
    je ne parlais même pas des sources des fichiers exemples , mais bien des sources "vcl" . Un simple clic et on y est (maintenant , la version éducation ne les fourni peut être pas )

    "Démarrer", "Tous les Programmes", "Embarcadero RAD Studio XE7", "Exemples" ....
    Et ensuite une fois qu'il ouvre le répertoire : "Object Pascal", "Database", "FireDAC"
    ça , c'est depuis que firedac est vraiment inclus dans XE

    lors de sa 'parution' Firedac s'installait à part , n'ayant qu'XE4 je trouve mon bonheur ici (doc et exemples)
    C:\Program Files (x86)\Embarcadero\FireDAC
    et sur le site de anydac
    bien sur faut pas être allergique à l'anglais

    Peut-être est-ce pour un SQLLocal
    parlant du SQL local ne serait-ce pas une solution à exploiter dans ton contexte (le truc qui s'installerait sans dll de plus ? à vérifier)
    je reviens dessus , je n'avais pas fait attention mais :
    - tu copies vers du SQLite
    et
    La fonctionnalité SQL local .... est basée sur la base de données SQLite et supporte une grande partie du dialecte SQL de SQLite.
    il faudrait alors voir en déploiement ce qui est demandé (je passe la main)
    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

  17. #17
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    j'ai bien fait de ne pas conclure la discussion.

    J'ai rencontré plusieurs problèmes avec le BatchMove...

    Un premier que je ne comprenais pas, vu que le transfert entre une table mySQL et une table SQLite3:memory: avait fonctionné puis ne fonctionnait plus. Et parallèlement, j'ai essayé entre-temps avec le code défaillant, mySQL->mySQL (OK), mySQL->SQLite3 base en dur 'OK'...

    Problème : un SELECT COUNT(*) sur la table en mémoire me renvoyait 0 alors qu'une tentative de REmove m'envoyait une erreur sur la Primary Key m'indiquant que la table n'était pas vide. J'ai suspecté un problème de commit... et j'ai alors testé sur des tables en dur. Non, là n'était pas le problème. Finalement, j'ai remonté l'histoirique de mes codes (j'ai branché mon mercurial sur mes projets indépendamment de Delphi comme je le faisais pour Lazarus. )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    with FDBatchMoveDataSetWriter1 do begin
      Optimise := False; {Indispensable sur une table SQLite:memory:}
      DataSet := SQLiteModule.SQLiteQuery;
    end;
    C'est le Optimise := False; que j'avais introduit au départ puis enlevé ensuite. Normalement c'est lié à une histoire de dbGrid et dans le cas précis, je n'en ai pas. Je passe directement d'une base à l'autre. Pour des tables en dur, on peut s'en passer.

    Alors ensuite j'ai un problème de WideMemo à l'affichage dans les dbGrids
    Si je construis ma table SQLite ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Add('CREATE TABLE `sqliteELV`');
    Add('(');
    Add('`elID` CHAR( 20 ) ,');
    Add('`elCODE` VARCHAR( 6 ),');
    Add('`elINSEE` VARCHAR( 50 ),');
    [...]
    la dbGrid reliée ensuite au SQLiteQuery affiche les données correctement.
    Mais CHAR, VARCHAR en SQLite c'est simplement du TEXT...
    Alors j'ai essayé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Add('CREATE TABLE `sqliteELV`');
    Add('(');
    Add('`elID` TEXT,');
    Add('`elCODE` TEXT,');
    Add('`elINSEE` TEXT,');
    [...]
    Ma dbGrid m'affiche alors dans toutes les cellules un (WIDEMEMO)... mais j'ai le bon nombre de lignes

    Je savais bien que cela allait se compliquer. Il semble que ShailLeTroll ait proposé une solution : http://www.developpez.net/forums/d14...lite-widememo/... J'ai testé sur un BLOBTEXT de mySQL vers un TEXT de SQLite. Comme d'habitude la proposition de ShailLeTroll fonctionne sans problème. Mais je ne la retiens que pour les BLOBTEXT initiaux pas pour les VARCHAR.
    Et j'ai trouvé d'autres messages à ce sujet : https://groups.google.com/forum/#!to...er/xVamJUpXASM.

    Je vais donc garder mes déclarations VARCHAR au lieu de TEXT dans mes tables SQLite (et mes BOOLEAN aussi qui posent un problème de conversion également) ... qui ne sont visiblement pas équivalentes quoi qu'en disent plein d'articles très sérieux... et quoi que propose la plupart des éditeurs de tables SQLite. Il est vrai que dans les TEXT, on place aussi bien des VARCHAR que des BLOBTEXT. Ceci doit expliquer cela.

    Ici DB Browser for SQLite (5 types de champs sont proposés)
    Dernière modification par Invité ; 01/11/2014 à 13h06.

  18. #18
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Thierry Laborde Voir le message
    L'explorateur de données est là pour ça, et fonctionne sur tous les types de bases de données supportés par FireDAC.
    Bonjour,

    J'ai essayé mais ce n'était pas vraiment mon souci premier. J'ai une erreur à l'ouverture des tables. J'ai installé la sqlite3.dll au même endroit qu'une libmysql.dll (C:\Program Files (x86)\Embarcadero\Studio\15.0\bin). Ma connection définition "mysqlDistant" fonctionne parfaitement bien sur mes tables distantes...

    Mais tout ce qui est en SQLite3 génère l'erreur suivante.
    J'ai la même erreur avec SQLite_Demo.
    Et merci pour les autres infos.
    Dernière modification par Invité ; 01/11/2014 à 13h36.

  19. #19
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 857
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 857
    Points : 11 291
    Points
    11 291
    Billets dans le blog
    6
    Par défaut
    Bonjour,
    Au passage, la version 3.8.7 de SQLite (2014-10-17) a amélioré la fonction CAST avec la limitation que
    To cast a BLOB value to TEXT, the sequence of bytes that make up the BLOB is interpreted as text encoded using the database encoding.
    Mais les essais de Gilles n'ont pê pas été satisfaisants, même avec cette version de la bibliothèque ?
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  20. #20
    Invité
    Invité(e)
    Par défaut
    Bonjour Yves,

    Je dispose sous Win32 d'une 3.8.6 du 15/08/2014.
    Comme je veux affiner la question et celui des indexes, je télécharge la 3.8.7 et je fais un petit projet avec.
    Merci.
    Dernière modification par Invité ; 01/11/2014 à 18h38.

Discussions similaires

  1. Réponses: 2
    Dernier message: 13/10/2009, 12h55
  2. Probleme conversion fichier provenant d'une base oracle vers une base mysql
    Par jonnyboy dans le forum Développement de jobs
    Réponses: 3
    Dernier message: 18/06/2009, 09h40
  3. Réponses: 7
    Dernier message: 18/02/2008, 14h33
  4. Réponses: 2
    Dernier message: 10/07/2007, 10h04
  5. copie d'une table Y d'une base A vers une table X d'une base
    Par moneyboss dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 30/08/2005, 21h24

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