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 :

Transférer les données d'une table vers une autre table


Sujet :

Delphi

  1. #1
    Nouveau membre du Club
    Femme Profil pro
    Auditeur informatique
    Inscrit en
    Février 2019
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 25
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : Auditeur informatique
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2019
    Messages : 53
    Points : 37
    Points
    37
    Par défaut Transférer les données d'une table vers une autre table
    Bonjour tout le monde,

    Pour mon application de gestion de la paye, avec Delphi 10.3, Je doit écrire un algorithme qui permet de transférer TOUS les enregistrements d'une table vers une autre (table_temporaire vers table_paye). les deux tables ont exactement la même structure. En fait, la paye se calcul sur la table_temporaire ou on peux ajouter, supprimer, modifier comme on le souhaite, mais une fois le calcul terminé, J'aimerai qu'en cliquant sur le bouton VALIDER, TOUS les enregistrements de la table_temporaire soient transférés vers la table_paye ou ces derniers sont définitivement sauvegarder.

    Ce que je fait :

    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
    procedure TForm3.Button2Click(Sender: TObject);
     
     
    begin
      With ADOTable4 do
     
         begin
     
          ADOTable4.Insert ;
          ADOTable4['Id_rubrique_t'] := ADOTable3['Id_rubrique'];
          ADOTable4['Code_rubrique_t'] := ADOTable3['Code_rubrique'] ;
          ADOTable4['Designation_t'] := ADOTable3['Designation'] ;
          ADOTable4['Base_t'] := ADOTable3['Base'] ;
          ADOTable4['T_Pat_t'] := ADOTable3['T_Pat'] ;
          ADOTable4['T_Sal_t'] := ADOTable3['T_Sal'] ;
          ADOTable4['P_Pat_t'] := ADOTable3['P_Pat'] ;
          ADOTable4['P_Sal_t'] := ADOTable3['P_Sal'] ;
          ADOTable4.Post ;
          end;
     
     
       end;
    Mais ce dernier ajoute uniquement le seul et le dernier enregistrement
    Quelqu'un à une solution à me proposer ? merci par avance !

  2. #2
    Fxg
    Fxg est déconnecté
    Membre éclairé
    Homme Profil pro
    ingénieur financier
    Inscrit en
    Septembre 2003
    Messages
    510
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : ingénieur financier

    Informations forums :
    Inscription : Septembre 2003
    Messages : 510
    Points : 837
    Points
    837
    Par défaut
    Bonjour,

    Il faut partit du premier enregistrement et parcourir toute la table jusqu'au dernier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    with ADOQuery1 do
         begin
           open;
           first;
           while not eof do
               begin
                 // Lecture dans la première table
     
    // Ecriture dans la deuxième table
     
                 next;
               end;

  3. #3
    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,

    La réponse de Fxg est la première solution., encore que l'ordre des commentaires laisse à désirer, il faut lire le prochain enregistrement après avoir écrit dans la table cible !

    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
    procedure TForm3.Button2Click(Sender: TObject);
    begin
      With ADOTable4 do
         begin
          First;
          while not EOF do 
              begin 
                // insertion 
                ADOTable4.Insert ;
                ADOTable4['Id_rubrique_t'] := ADOTable3['Id_rubrique'];
                ADOTable4['Code_rubrique_t'] := ADOTable3['Code_rubrique'] ;
                ADOTable4['Designation_t'] := ADOTable3['Designation'] ;
                ADOTable4['Base_t'] := ADOTable3['Base'] ;
                ADOTable4['T_Pat_t'] := ADOTable3['T_Pat'] ;
                ADOTable4['T_Sal_t'] := ADOTable3['T_Sal'] ;
                ADOTable4['P_Pat_t'] := ADOTable3['P_Pat'] ;
                ADOTable4['P_Sal_t'] := ADOTable3['P_Sal'] ;
                try 
                    ADOTable4.Post ;
                except
                    // traitement erreur 
                     ADOTable4.Cancel  // annulation
                end;
                // lecture 
                Next; 
            end;
       end;
     end;

    Une solution plus élégante serait de passer, si c'est possible (cela dépend du SGBD), par un SQL
    par exemple
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    INSERT INTO TABLECIBLE (COL1,COL2,COL3) SELECT COL1,COL2,COL3 FROM TABLESOURCE

    donc
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INSERT INTO Table4 (id_rubrique,Code_Rubrique,Designation,Base,T_Pat,T_Sal,P_Pat,P_sal)  
      SELECT Id_rubrique_t,Code_rubrique_t,Designation_t,Base_t,T_Pat_t,T_Sal_t,P_Pat_t,P_Sal_t FROM Table3

    Avantages :
    - si id_rubrique est un auto-incrément, la colonne peut ne pas être indiquée
    - qui dit SELECT dit possibilité de toute sorte d'opération comme une clause WHERE par exemple


    Enfin une autre solution en utilisant les composants Firedac (FDConnexion,FDBatchMove,FDBatchMoveDatasetReader,FDBatchMoveDatasetWriter) est aussi envisageable
    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

  4. #4
    Nouveau membre du Club
    Femme Profil pro
    Auditeur informatique
    Inscrit en
    Février 2019
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 25
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : Auditeur informatique
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2019
    Messages : 53
    Points : 37
    Points
    37
    Par défaut
    Bonjour,

    Merci de vos réponses, mais un détail m’échappe toujours !

    Ce code semble correct portant aucun transfert n'est effectué sur la table
    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
    procedure TForm3.Button2Click(Sender: TObject);
    begin
      With ADOTable4 do
         begin
          First;
          while not EOF do 
              begin 
                // insertion 
                ADOTable4.Insert ;
                ADOTable4['Id_rubrique_t'] := ADOTable3['Id_rubrique'];
                ADOTable4['Code_rubrique_t'] := ADOTable3['Code_rubrique'] ;
                ADOTable4['Designation_t'] := ADOTable3['Designation'] ;
                ADOTable4['Base_t'] := ADOTable3['Base'] ;
                ADOTable4['T_Pat_t'] := ADOTable3['T_Pat'] ;
                ADOTable4['T_Sal_t'] := ADOTable3['T_Sal'] ;
                ADOTable4['P_Pat_t'] := ADOTable3['P_Pat'] ;
                ADOTable4['P_Sal_t'] := ADOTable3['P_Sal'] ;
                try 
                    ADOTable4.Post ;
                except
                    // traitement erreur 
                     ADOTable4.Cancel  // annulation
                end;
                // lecture 
                Next; 
            end;
       end;
     end;
    J'ai essayé avec ce code mais je ne sais pas pourquoi, ça ne fonctionne pas portant aucun message d'erreur n'est affiché après compilation du programme
    Peut-être faut une liaison spéciale entre les tables ? Le SGBD initialisé est accès 2010

  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,

    Avez-vous songé que l'insertion ne peut se faire si l'enregistrement existe déjà ? (lignes 20 - 23)

    Vous nous avez demandé de fournir un code tel que tous les enregistrements de la table temporaire soient envoyés en table "permanente", dont acte.
    Toutefois si la demande avait été différente : "ajouter ou modifier les enregistrements de la table permanente" quelques lignes de plus auraient été nécessaires : un simple test d'existence sur la table permanente !

    ligne 9 :If Adotable4.FindKey(ADOTable3['Id_rubrique']) then Adotable4.Edit else ADOTable4.Insert;À ce propos j'ai un méaculpa à faire
    Le fait que vous n'ayez pas donné des noms explicites à vos composants en explique certainement la cause DONNEZ DES NOMS EXPLICITES AUX COMPOSANTS (j'aurais pu utiliser le smiley mais je ne veux pas être taxé #porc)
    Dans le code que j'ai proposé le with ADOTable4 do est faux, selon le reste du code c'est with ADOTable3 dode même, j'ai un gros doute, j'ai l'impression que vous vous êtes trompée dans l'affectation des colonnes !

    Si dans les noms de colonnes le suffixe "_t" indique qu'il s'agit d'une colonne de la table temporaire et que vous voulez copier de la table temporaire vers la table "permanente" alors vous vous êtes fourvoyée dans le sens de copie !
    ADOTable3 -> T_Temporaire
    ADOTable4 -> T_Cible

    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 TForm3.CopierVersClick(Sender: TObject);
    begin
          T_Temporaire.First;
          while not T_Temporaire.EOF do 
              begin 
                // insertion 
                if T_Cible.Findkey(T_Temporaire['Id_rubrique']) then T_Cible.Edit else T_Cible.Insert ;
                T_Cible['Id_rubrique'] := T_Temporaire['Id_rubrique'];
                T_Cible['Code_rubrique'] := T_Temporaire['Code_rubrique_t'] ;
                T_Cible['Designation'] := T_Temporaire['Designation_t'] ;
                T_Cible['Base'] := T_Temporaire['Base_t'] ;
                T_Cible['T_Pat'] := T_Temporaire['T_Pat_t'] ;
                T_Cible['T_Sal'] := T_Temporaire['T_Sal_t'] ;
                T_Cible['P_Pat'] := T_Temporaire['P_Pat_t'] ;
                T_Cible['P_Sal'] := T_Temporaire['P_Sal_t'] ;
                try 
                    T_Cible.Post ;
                except
                    // traitement erreur 
                     T_Cible.Cancel  // annulation
                end;
                // lecture 
                T_Temporaire.Next; 
            end;
     end;
    NOTES :
    - J'en ai même ôté ces instructions with qui floutent plus que ne sont utiles
    - Pour l'instruction FindKey j'ai un doute, mais je n'irais pas faire la vérification, ADO et Access, je l'ai souvent écrit, ce n'est pas ma tasse de thé
    - maintenant que le SGBD a été indiqué je confirme que la requête indiquée est possible https://docs.microsoft.com/fr-fr/off...oft-access-sql
    - malheureusement ce même "SGBD" (notez que je l'ai mis entre guillemets pour exprimer mon désaveu d'Access) ne permet pas de faire des instructions de type UPDATE OR INSERT
    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

  6. #6
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 496
    Points : 2 762
    Points
    2 762
    Billets dans le blog
    10
    Par défaut
    Je pense, remplacer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      With ADOTable4 do
         begin
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      With ADOTable3 do
         begin

  7. #7
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 419
    Points : 5 818
    Points
    5 818
    Par défaut
    salut

    si c'est sur une meme base
    autant utiliser le sql c' seras toujours plus rapide qu'un boucle et un post en fin de boucle

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Insert into T_Cible(CH1,CH2,...)
    select CH1,CH2,...
    From T_TEMPORAIRE
    si il existe des condition particulière tu peut ajouter des filtre
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  8. #8
    Nouveau membre du Club
    Femme Profil pro
    Auditeur informatique
    Inscrit en
    Février 2019
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 25
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : Auditeur informatique
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2019
    Messages : 53
    Points : 37
    Points
    37
    Par défaut
    Bonjour,

    Merci de vos réponse !

    Le programme fonctionne bien, En fait, fallait juste faire :
    With ADOTable3 do
    Au lieu de

    With ADOTable4 do
    Et ça fonctionne bien !

    C'est vrai y avait confusion dans le transfère des enregistrements entre table et cela est bien corrigé !
    Merci @SergioMaster pour ton idée de donner des noms explicite à chaque composant, et cela est bien fait !

    mais apparemment la deuxième solution proposé par SergioMaster en utilisant SQL est plus élégante et j'aimerai bien par cette occasion apprendre à l'utiliser
    si j'ai donc bien compris, faut utiliser ADOQuery au lieu de ADOTable et la propriété SQL du ADOQuery,
    Mais dans ce cas la requête SQL proposé sera utiliser plutot à la place du code du bouton valider toujours ou bien sur la propriété SQL de ADOQuery ?

  9. #9
    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
    Citation Envoyé par mimiferry Voir le message
    Merci @SergioMaster pour ton idée de donner des noms explicite à chaque composant !
    Cela devrait être systématique, pensez toujours "et si je devais faire de la maintenance sur le programme"
    Mais apparemment la deuxième solution proposée par SergioMaster en utilisant SQL est plus élégante et j'aimerais bien par cette occasion apprendre à l'utiliser
    anapurna aussi l'a proposée. Cette solution est plus élégante dans le sens où c'est le SGBD qui fait le boulot et non le programme

    si j'ai donc bien compris, faut utiliser ADOQuery au lieu de ADOTable et la propriété SQL du ADOQuery,
    oui

    Mais dans ce cas la requête SQL proposé sera utiliser plutôt à la place du code du bouton valider toujours?
    Dans le code de l'événement OnClick du bouton par un simple ExecSQL

    ici, une version qui évite de poser un TADOQuery sur la forme (création au runtime)
    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
    procedure TForm3.CopierVersClick(Sender: TObject);
    var aQuery : TAdoQuery;
         n : integer;
    begin
    aQuery:=TADOQuery.Create(Self);  // création du composant
    try
      aQuery.Connection:=Connexionbase;   // Connexionbase = Adoconnection1 
      // bien sûr il faut remplacer Table4 et Table3 par les bons noms de table 
      aquery.SQL.text:='INSERT INTO Table4 (id_rubrique,Code_Rubrique,Designation,Base,T_Pat,T_Sal,P_Pat,P_sal)';  
      aQuery.SQL.Add('SELECT Id_rubrique_t,Code_rubrique_t,Designation_t,Base_t,T_Pat_t,T_Sal_t,P_Pat_t,P_Sal_t FROM Table3');
     try
        n:=aQuery.ExecSQL;   // exécution du SQL, pour le plaisir on récupére le nombre d'insertions 
        Showmessage(format('copie de %d enregistrements',[n]));
     except
        Showmessage('Erreurs'); // penser à gérer le cas où doublons 
     end; 
    finally
     aQuery.Free;  // "supprime" le composant
    end; 
    end;
    P.S. Il doit même y avoir plus simple, exécuter une commande directement avec la connexion mais ADO et moi ...
    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. [WD23] Transférer les données d'une tablette vers base MSSQL SERVER
    Par Invité dans le forum WinDev
    Réponses: 0
    Dernier message: 31/05/2018, 09h59
  2. [XL-2010] Comment transférer les données d'une ListBox vers une TextBox
    Par TSAFACK-M dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 23/11/2016, 09h00
  3. Transférer les données d'une JTable vers une autre
    Par rollbich dans le forum Composants
    Réponses: 4
    Dernier message: 19/01/2006, 23h22
  4. Transférer les données d'une base d'un coup
    Par martonpylon12 dans le forum Access
    Réponses: 6
    Dernier message: 12/10/2005, 20h43
  5. récupérer juste les données d'une autre table
    Par rangernoir dans le forum Access
    Réponses: 5
    Dernier message: 13/09/2005, 14h52

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