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

Delphi Discussion :

Delphi client /serveur Insertion des données


Sujet :

Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Mars 2013
    Messages
    212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mars 2013
    Messages : 212
    Par défaut Delphi client /serveur Insertion des données
    Salut,
    Je veux savoir une chose concernant les applications client/ server , que je cherche depuis longtemps ,
    Pour une application client /server quelle est la meilleur méthode pour insérer les données?
    1-query.append puis remplir les champs (dbedit) puis query.post ; (Moi j'utilise ça).
    2-insert into table (.....) valus (......);
    Je pose Ma question parce que des programmeurs m'ont recommandé d'utiliser la 2eme méthode pour éviter les problèmes si deux utilisateurs insèrent des données en même temps , Je vous prie , j'ai besoin de l'aide .

  2. #2
    Rédacteur/Modérateur

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

    s'il s'agit d'un vote je vote sans hésitation pour la solution 2 quoique pas pour les mêmes raisons (ou du moins pas que).
    Append pour tout bon SGBD et table bien conçue (à minima une colonne auto-incrémentée) ne sert à rien et peut même peut-être être à contrario improductif (selon le SGBD). Il n'est absolument pas nécessaire de garder en ordre les lignes à partir du moment où vous avez une colonne indexée.

    [Edit] Et encore j'ai considéré que le Append....Post était exécuté dans un même bloc de code sans possible manipulation(s) par un utilisateur. pour moi, "une bonne opération sur BDD est une opération courte"

  3. #3
    Membre émérite
    Homme Profil pro
    Chef de projets retraité
    Inscrit en
    Juillet 2011
    Messages
    455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : Chef de projets retraité
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2011
    Messages : 455
    Par défaut
    Bonjour

    1/
    * Query append => tu bloques quelque chose (table, colonne...) aucun autre client n'y accède en écriture (et parfois en lecture selon le SGBD)
    * DbEdit => On peut supposer que c'est l'utilisateur qui remplit les champs Si son collègue vient le chercher pour boire un café cela peut durer un certain temps (cf Fernand Reynaud)
    * Query post => Tu fais ta mise à jour et tu laisse les autres accéder à tes données (si cela a duré longtemps il est probable que quelques autre utilisateurs ont abandonné) => Principes d'ergonomie

    2/ Insert (ou Update) Tu ne bloques que pendant la mise à jour soit un minimum de temps et surtout sans attente de l'utilisateur.
    * Pour être sûr (dans un contexte multi utilisateur lourd) je
    - démarrerait une transaction
    - Vérifierait que les conditions de la mise à jour sont valides (pas de création d'une ligne avec les mêmes identifiants fonctionnels ou pas de modification d'un colonne de la ligne que je veux modifier pendant la saisie)
    + Si OK alors traitement (insert/update) et commit
    + Si KO alors rollback et demande à l'utilisateur quelle action mettre en œuvre
    Donc selon moi le point 2 est largement préférable car il limite les blocages de la base

    Cordialement

  4. #4
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 978
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 978
    Par défaut
    C'est fou comme les rôles s'inversent avec le temps.
    Ah la nostalgie de mes débuts où je venais demander conseil à mon chef de projet !
    Alors qu'aujourd'hui, mon chef de projet fait plus de management qu'autre chose et c'est lui qui viens me poser des questions techniques

    En tout cas, tes deux programmeurs ont raison.
    La deuxième méthode est à préférer.

  5. #5
    Membre très actif
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Mars 2013
    Messages
    212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mars 2013
    Messages : 212
    Par défaut
    je vous remercie pour la repense , maintenant j'ai compris la différence entre les deux Procédures , Aprés ça j'ai fait un essai , car je suis habitué sue le premier Procédure, c'est pour j'ai commencer à traiter le deuxieme , donc j'ai fait un petit essai :
    Q:Adoquery et comm:Adocommand et con:Adoconnection et etude :la table crée sur sql server 2008
    1-button:Ajout
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure TForm1.Button1Click(Sender: TObject);
    begin
    Q.Insert;
    end;
    2-button :Valider :
    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
    procedure TForm1.Button2Click(Sender: TObject);
    begin
    try
    con.BeginTrans;
    comm.CommandText:='';
    comm.CommandText:='insert into etude (Num,Nom,dat) values (:p,:b,:c)  ';
    comm.Parameters.ParamByName('p').value:=dbedit1.Text;
    comm.Parameters.ParamByName('b').value:=dbedit2.Text;
    comm.Parameters.ParamByName('c').value:=dbedit3.Text;
    comm.Execute;
     
    Q.SQL.Clear;
    Q.SQL.text:='select * from etude order by Num';
    Q.ExecSQL;
    q.Open;
    con.CommitTrans;
    except
    on e:exception do
    begin
    con.RollbackTrans;
    showmessage(E.Message);
    exit;
    end;
    end;
    end;
    3-button:Supprimer
    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
    procedure TForm1.Button3Click(Sender: TObject);
    begin
    try
    comm.CommandText:='';
    comm.CommandText:='delete from etude where num=:p  ';
    comm.Parameters.ParamByName('p').value:=dbedit1.Text;
    comm.Execute;
     
    Q.SQL.Clear;
    Q.SQL.text:='select * from etude order by Num';
    Q.ExecSQL;
    q.Open;
    except
      on E:exception do
      showmessage(E.Message);
    end;
    end;
    4-button4:Mettre à jour:
    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
    procedure TForm1.Button4Click(Sender: TObject);
    begin
    try
    con.BeginTrans;
    comm.CommandText:='';
    comm.CommandText:='update etude set  nom = :b , dat = :c  where Num =  :p ';
    comm.Parameters.ParamByName('p').value:=dbedit1.Text;
    comm.Parameters.ParamByName('b').value:=dbedit2.Text;
    comm.Parameters.ParamByName('c').value:=dbedit3.Text;
    comm.Execute;
     
    Q.SQL.Clear;
    Q.SQL.text:='select * from etude order by Num';
    Q.ExecSQL;
    q.Open;
    con.CommitTrans;
    except
    on e:exception do
    begin
    con.RollbackTrans;
    showmessage(E.Message);
    exit;
    end;
    end;
    end;
    --------------------------
    Je vous demande d'évaluer mon petit travaille.je suis loin ,prêt,bon....et Merci d'avance.

  6. #6
    Rédacteur/Modérateur

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

    en préambule deux choses
    1. d'abord sur la forme, prenez l'habitude d'utiliser les balises de code (bouton #) pour encadrer votre code, c'est plus facile à lire et permet une syntaxe visible
    2. ensuite pour vous prévenir que je suis loin d'être un adepte de ADO



    Je vais commencer par la procédure "supprimer" symptomatique de l'ensemble des procédures que vous avez écrites

    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
     
    try
    comm.CommandText:='';
    comm.CommandText:='delete from etude where num=:p  ';
    comm.Parameters.ParamByName('p').value:=dbedit1.Text;    // voir en dessous  
    comm.Execute;
    Q.Close; // vous changez le SQL donc vous devez fermer l'ensemble ouvert
    // Q.SQL.Clear; inutile
    Q.SQL.text:='select * from etude order by Num'; // A mon avis, inutile car c'est déjà le SQL de votre Query
    // Q.ExecSQL;  // inutile 
    q.Open; 
    except
      on E:exception do
        showmessage(E.Message);
    end;
    Plus complexe la partie paramètre, ce qui m'interpelle c'est que vous passiez dans vos paramètre des composants liés au datasource DBxxxxxxx
    J'aurais plutôt écrit q.fieldByName(champ).asString (ou aslebontype). Bien sûr n'étant pas un ADOPhile (cf. 2 ) j'ai d'abord pensé au composant UpdateSQL qui aurait permis de gérer les différentes possibilités sans tout ces CommandText !

    Autre point, négatif à mon avis, si votre utilisateur "voit" l'avancement de ces travaux au travers d'une grille, je suis sûr qu'il sera vite énervé de toujours revenir en début de table !
    Ajoutez une mémorisation de la clé, un repositionnement et quelques instructions pour éviter le "flickering"
    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
     
    var keypos : String;
    begin
    Q.DisableControls;  // la grille ne "bouge" plus
    KeyPos:=Q.FieldByName('Num').asString; // mémorisation de la position
    try 
     try
      comm.CommandText:='';
      comm.CommandText:='delete from etude where num=:p  ';
      comm.Parameters.ParamByName('p').value:=dbedit1.Text;    // voir en dessous  
      comm.Execute;
      Q.Close; // vous changez le SQL donc vous devez fermer l'ensemble ouvert
    // Q.SQL.Clear; inutile
      Q.SQL.text:='select * from etude order by Num'; // A mon avis, inutile car c'est déjà le SQL de votre Query
      Q.Locate('NUM',Keypos,[loPartialKey]); // recherche au plus proche
    // Q.ExecSQL;  // inutile 
      q.Open; 
     except
      on E:exception do
        showmessage(E.Message);
     end;
    finally
     Q.EnableControls;
    end;
    end;
    en PS pourquoi des exits AMHA inutiles dans vos deux blocs try except ?

  7. #7
    Membre très actif
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Mars 2013
    Messages
    212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mars 2013
    Messages : 212
    Par défaut
    Citation Envoyé par acaumes Voir le message
    Bonjour

    1/
    * Query append => tu bloques quelque chose (table, colonne...) aucun autre client n'y accède en écriture (et parfois en lecture selon le SGBD)
    * DbEdit => On peut supposer que c'est l'utilisateur qui remplit les champs Si son collègue vient le chercher pour boire un café cela peut durer un certain temps (cf Fernand Reynaud)
    * Query post => Tu fais ta mise à jour et tu laisse les autres accéder à tes données (si cela a duré longtemps il est probable que quelques autre utilisateurs ont abandonné) => Principes d'ergonomie

    2/ Insert (ou Update) Tu ne bloques que pendant la mise à jour soit un minimum de temps et surtout sans attente de l'utilisateur.
    * Pour être sûr (dans un contexte multi utilisateur lourd) je
    - démarrerait une transaction
    - Vérifierait que les conditions de la mise à jour sont valides (pas de création d'une ligne avec les mêmes identifiants fonctionnels ou pas de modification d'un colonne de la ligne que je veux modifier pendant la saisie)
    + Si OK alors traitement (insert/update) et commit
    + Si KO alors rollback et demande à l'utilisateur quelle action mettre en œuvre
    Donc selon moi le point 2 est largement préférable car il limite les blocages de la base

    Cordialement
    Merci c'est ça ce que je pensais depuis longtemps , regarde ce code pr exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     
    begin
      conn.beginTranS;
      try
        Q.Insert;
       Q.FieldByName('name').AsString := dbedit1.text;
        Q.Post;
       conn.committrans;
      except
        conn.Rollback;
      end;
    end;
    Mais ce que je voie ici ,si j' utilise des dbedit.text Es ce que je pourrais separer q.insert; dans un button et le reste dans un autre button? Si non je dois forcement utiliser des edit.text.

  8. #8
    Rédacteur/Modérateur

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

    il ne faut pas confondre datasource et table de la BDD !
    je vais schématiser :
    l'instruction Q.Insert met le datasource en mode insertion (rien n'est fait au niveau de la BDD) les colonnes du datasource elles sont disponibles
    le DBEdit,est lié au datasource pas directement à la table dans la BDD.

    Je pense que ma phrase
    ce qui m'interpelle c'est que vous passiez dans vos paramètre des composants liés au datasource DBxxxxxxx
    J'aurais plutôt écrit q.fieldByName(champ).asString
    est passée inaperçue, j'aurais certainement mettre explicitement le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    comm.CommandText:='';
    comm.CommandText:='delete from etude where num=:p  ';
    comm.Parameters.ParamByName('p').value:=q.FieldByName('num').asString;  
    comm.Execute;
    votre dernier code est "étrange"
    vous passez la commande Insert donc Q.FieldByName('Nom').asString='' subséquement DBEdit1.Text s'il est lié à la colonne nom contient ''
    l'instruction suivante Q.FieldByName('name').AsString := dbedit1.text; ne fait donc strictement rien (c'est déjà fait par le datasource) s'il n'y a eu aucun changement fait par l'utilisateur (et là votre code ne semble pas le permettre)

    Est ce que je pourrais séparer q.insert; dans un button et le reste dans un autre button?
    Bien évidemment référez vous au début : "l'instruction Q.Insert se fait sur le datasource"

    c'est vraiment là ou ADO n'est pas mon truc ! ce serait si simple de le montrer avec une Query+TUpdateSQL

  9. #9
    Membre très actif
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Mars 2013
    Messages
    212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mars 2013
    Messages : 212
    Par défaut
    l'instruction Q.Insert met le datasource en mode insertion (rien n'est fait au niveau de la BDD)
    Merci ,Mais regarde ce qu'il disait Acaumes :
    * Query append => tu bloques quelque chose (table, colonne...) aucun autre client n'y accède en écriture (et parfois en lecture selon le SGBD)
    ---
    Je vois ici une contradiction.

    ce que j'ai appris jusq'à maintenant :
    Il vaux mieux utliser des Edit pour Inserer de cette manière
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    begin
      conn.beginTranS;
      try
        Q.Insert;
       Q.FieldByName('name').AsString := edit1.text;
        Q.Post;
       conn.committrans;
      except
        conn.Rollback;
      end;
    end;
    Pour eviter des conflits si un autre urtilisateur insère des données .
    un autre point l'utilisation de Updatesql , J'ai cherché depuis longtemps sur le net et j'ai rien trouvé comme exemple.
    Sans dirangement Je veux un exemple d'opérations sur une table .(insert,Update,) en utilisant des buttons pour une traitement complet.
    Merci et cordialement.

Discussions similaires

  1. [TOS] - Performance insertion des données en base locale et serveur distant
    Par mighty nagty dans le forum Développement de jobs
    Réponses: 4
    Dernier message: 04/02/2016, 17h00
  2. Réponses: 10
    Dernier message: 09/08/2015, 23h47
  3. [Serveur/Client] ObjectInputStream -> Lire des données envoyés
    Par moithibault dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 13/06/2011, 17h15
  4. Réponses: 5
    Dernier message: 21/12/2007, 08h24
  5. Réponses: 6
    Dernier message: 04/05/2005, 09h58

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