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 :

Problème pour insertion après 'multiples' création de table


Sujet :

Bases de données Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    sans
    Inscrit en
    Mars 2020
    Messages
    182
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : sans

    Informations forums :
    Inscription : Mars 2020
    Messages : 182
    Par défaut Problème pour insertion après 'multiples' création de table
    Bonjour

    Je ne sais pas si je dois poster ici ou dans la section composant car le message d erreur inclut aussi le nom du composant...

    Je m initie à FireDac + Sqlite et je rencontre un probleme que j ai pu identifier mais que je ne sais solutionner :

    Si j execute le code tel quel, tout fonctionne, je peux remplir ma table tb_import.

    Par contre si je décommente les lignes, c est à dire que je crée la table tb_trades ma table est bien crée mais il m est alors impossible de remplir la table tb_import. J'ai un message [firedac][phys][sqlite]'syntaxe error' près de INSERT alors même que cette requête fonctionne parfaitement si je n ai pas créé la table tb_trades.

    Mon code :
    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
    result := true;
      with form1.qry do
      begin
        sql.clear;
        sql.add('DROP Table IF EXISTS "tb_import";');
        sql.add(
          'CREATE Table "tb_import" (	"id"	INTEGER PRIMARY KEY AUTOINCREMENT,"Jour"	TEXT,"Heure"TEXT,"price_open"	REAL,"price_high" REAL,"price_low" REAL,"price_close"	REAL);');
    //    sql.add('DROP Table IF EXISTS "tb_trades";');
    //    sql.add
    //      ('CREATE Table "tb_trades" (	"id"	INTEGER PRIMARY KEY AUTOINCREMENT,"Jour"	TEXT,"Heure"	TEXT,	"price_open"	REAL,	"price_high"	REAL,	"price_low"	REAL,	"price_close"	REAL)');
        try
          ExecSQL;
        except
          result := false;
        end;
      end;
    Je suis totalement perdu car j imagine que ce peut etre aussi du à une propriété du TFDConnection ou du TFDQuery....

    Merci pour vos conseils et votre aide.

  2. #2
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 628
    Billets dans le blog
    65
    Par défaut
    Bonjour,

    pour créer un ensemble de tables, passez par un FDScript (syntaxe) plutôt que par un FDQuery.
    solution 1 : vous écrivez le tout directement au design
    - un FDScript est posé sur la forme, la connexion indiquée
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    DROP Table IF EXISTS tb_import;
    CREATE Table tb_import(id INTEGER PRIMARY KEY AUTOINCREMENT,Jour	TEXT,Heure TEXT,price_open	REAL,price_high REAL,price_low REAL,price_close REAL);
    DROP Table IF EXISTS tb_trades;
    CREATE Table tb_trades (id	INTEGER PRIMARY KEY AUTOINCREMENT,Jour	TEXT,Heure	TEXT, price_open	REAL,price_high	REAL,price_low	REAL,price_close	REAL);
    NOTE : vous remarquerez que j'ai enlevé les guillemets des noms de tables et de colonnes, mettre les guillemets rend les noms sensible à la casse vous serez bien moins embêter si vous ne les mettez pas. En ce qui concerne le script, je n'ai fait que reprendre votre code, je n'ai pas étudié la structure sensu-stricto mais déjà, ce qui me choque ce sont les colonnes Date et Heure que vous aurez du mal à traiter via SQL

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    if FDScript1.ValidateAll then 
    begin
       FDConnection1.StartTransaction;
      try
        FDScript1.ExecuteAll;
      finally
       if FDScript1.TotalErrors > 0 then
          FDConnection1.Rollback
       else
          FDConnection1.Commit;
       end;
       result:=FDScript1.TotalErrors=0; // si besoin
    solution 2 : vous remplissez le script au runtime (même pas besoin de poser de FDScript sur la forme, enfin, plus exactement vous posez un FDScript, vous sauvegardez le source puis vous supprimer le FDScript ainsi vous aurez les uses nécessaires.)

    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
     
    with TFDScript.Create(Self) do
      begin
         Connexion:=FdConnection1;
     {$REGION 'Préparation du script'} 
        Add;
        with SQLScripts[0].SQL do begin
         Add('DROP TABLE IF EXISTS tb_import');
         Add('CREATE TABLE tb_import(id INTEGER PRIMARY KEY AUTOINCREMENT,Jour	TEXT,Heure TEXT,price_open	REAL,price_high REAL,price_low REAL,price_close REAL)');
         Add('DROP TABLE IF EXISTS tb_trades');
         Add('CREATE Table tb_trades (id	INTEGER PRIMARY KEY AUTOINCREMENT,Jour	TEXT,Heure	TEXT, price_open	REAL,price_high	REAL,price_low	REAL,price_close	REAL)');
       end;
    {$ENDREGION}
    {$REGION 'Exécution du script'} 
    // même principe que plus haut    
      if ValidateAll then 
      begin
        FDConnection1.StartTransaction;
        try
         ExecuteAll;
       finally
        if TotalErrors > 0 
            then FDConnection1.Rollback
            else  FDConnection1.Commit;
       end;  
       result:=TotalErrors=0; // si besoin et si inclus dans une fonction 
      end; 
    {$ENDREGION}
     end;
    Note : Code écrit à la volée donc, non testé, il y a peut-être quelques erreurs d'imbrications begin end;

    pour finir deux points qui me choquent au niveau code
    with form1.qry do ce n'est pas la peine de mettre form1 à moins que qry se trouve dans une autre unité, et, dans ce cas, autant que ce qry soit dans un datamodule
    l'utilisation de result sauf si ce code est inclus dans une fonction évitez d'utiliser ce mot clé

  3. #3
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 937
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 937
    Par défaut
    Citation Envoyé par MoiStéphane Voir le message
    Par contre si je décommente les lignes, c est à dire que je crée la table tb_trades ma table est bien crée mais il m est alors impossible de remplir la table tb_import. J'ai un message [firedac][phys][sqlite]'syntaxe error' près de INSERT alors même que cette requête fonctionne parfaitement si je n ai pas créé la table tb_trades.
    Il manque un point-virgule à la fin de la commande CREATE Table "tb_trades".

  4. #4
    Membre confirmé
    Homme Profil pro
    sans
    Inscrit en
    Mars 2020
    Messages
    182
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : sans

    Informations forums :
    Inscription : Mars 2020
    Messages : 182
    Par défaut
    Il manque un point-virgule à la fin de la commande CREATE Table "tb_trades".
    @ Andnotor
    MERCI ! Je suis un âne. J ai passé des heures à lire, relire le code, à envisager tout un tas de solutions sans m apercevoir de cela...

    @ SergioMaster
    Merci pour ces excellents conseils.

    effectivement with form1.qry do est du au fait que qry se trouve sur le form principal.
    J'essaie autant que possible de séparer les traitements et les mettre dans une unité dédiée.
    J'imagine que dans l absolue je devrais passer qry à la fonction de traitement mais il faut mettre les uses et je ne sais lesquelles sont spécifiques à ce composant tant il y en a... ou mieux créer le composant à la volée

    Donc question : si je recopie l intégralité des unités Firedac de mon main form est-ce que l ors de la compilation seules les unités nécessaires sont 'compilées' ou l exe va être inutilement alourdi ?

  5. #5
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 628
    Billets dans le blog
    65
    Par défaut
    Généralement, tout ce qui est connexion aux données devraient se trouver dans une unité spécifique, un module de données. En terme pro on parle de séparer la couche métier de la couche interface utilisateur

    Donc question : si je recopie l intégralité des unités Firedac de mon main form est-ce que lors de la compilation seules les unités nécessaires sont 'compilées' ou l'exe va être inutilement alourdi ?
    Je ne comprends pas le terme recopier, et non même si plusieurs formes utilisent les unités Firedac cela n'alourdira pas le programme

  6. #6
    Membre confirmé
    Homme Profil pro
    sans
    Inscrit en
    Mars 2020
    Messages
    182
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : sans

    Informations forums :
    Inscription : Mars 2020
    Messages : 182
    Par défaut
    Merci

    Quand j écris recopier je voulais dire recopier les déclarations, c était simplement un raccourci de langage

  7. #7
    Membre confirmé
    Homme Profil pro
    sans
    Inscrit en
    Mars 2020
    Messages
    182
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : sans

    Informations forums :
    Inscription : Mars 2020
    Messages : 182
    Par défaut
    @ SergioMaster

    Généralement, tout ce qui est connexion aux données devraient se trouver dans une unité spécifique, un module de données. En terme pro on parle de séparer la couche métier de la couche interface utilisateur
    Je suis donc ce conseil et ai dédié une unité à tout ce qui est acces aux données. J y crée un TFDConnection et un TFDQuery et cela fonctionne parfaitement en respectant cette structure :
    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
    function Konnect(): TFDConnection;
    var
      Conn: TFDConnection;
    begin
      Conn := TFDConnection.Create(nil);
      Conn.Params.DriverID := 'SQLite';
      Conn.Params.Database := 'database.db';
      result := Conn;
    end;
     
    function Kry(): TFDQuery;
    var
      Qry: TFDQuery;
    begin
      Qry := TFDQuery.Create(nil);
      result := Qry;
    end;
     
    procedure Fill_Combo_Spread();
    var
      Conn: TFDConnection;
      Qry: TFDQuery;
    begin
      Conn := Konnect();
      Qry := Kry();
      Qry.Connection := Conn;
     
      Qry.Free;
      Conn.Free;
    end;
    Mais je souhaite la simplifier avec le code suivant et bien que cela fonctionne j ai une fuite mémoire car le TFDConnection n est jamais liberé selon moi.
    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
    function Konnect(): TFDConnection;
    var
      Conn: TFDConnection;
    begin
      Conn := TFDConnection.Create(nil);
      Conn.Params.DriverID := 'SQLite';
      Conn.Params.Database := 'database.db';
      result := Conn;
    end;
     
    function Kry(): TFDQuery;
    var
      Qry: TFDQuery;
    begin
      Qry := TFDQuery.Create(nil);
      Qry.Connection := Konnect();
      result := Qry;
    end;
     
    procedure Fill_Combo_Spread();
    var
      Qry: TFDQuery;
    begin
      Qry := Kry();
     
     
      Qry.Free;
     
    end;
    Donc ma question : serait il possible de 'forcer' la libération du TFDConnection au moment de la libération du TFDQuery ?

    Ou existe t il une façon plus élégante/performante de procéder ?

    Merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème pour insertion dans tables avec jointure
    Par C3DRIC49 dans le forum Langage
    Réponses: 8
    Dernier message: 15/10/2010, 21h52
  2. Problème pour lire les donnée d'une table externe
    Par mardoch dans le forum SQL*Loader
    Réponses: 6
    Dernier message: 17/07/2008, 16h41
  3. Réponses: 18
    Dernier message: 12/06/2006, 09h39
  4. Réponses: 2
    Dernier message: 10/02/2006, 14h46
  5. Réponses: 2
    Dernier message: 22/01/2006, 01h11

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