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 :

[Firebird] Ajout d'enregistrements sur une table de liaison


Sujet :

Bases de données Delphi

  1. #1
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut [Firebird] Ajout d'enregistrements sur une table de liaison
    Bonjour à tous

    J'ai un petit souci (sinon, je n'écrirais pas ici )
    J'ai une base qui contient une table Contacts, une table Adresses et une table faisant la liaison entre les 2:
    Table T_CONTACTS
    CONT_ID : clé primaire
    Données...
    Table T_ADRESSES
    ADR_ID : clé primaire
    Données...
    Table T_CONTACTS_ADRESSES
    CONT_ID,
    ADR_ID
    A première vue, rien de difficile, cette structure me permet évidemment de pouvoir lier plusieurs adresses à un contact.
    Afin de pouvoir modifier les adresses d'un contact, j'ai ajouté un TSQLQuery, un TDataSetprovider, un TClientDataSet et un TDataSource.
    J'ai créé une vue de cette façon:
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    SELECT
      CA.ADR_ID,
      CA.CONT_ID,
      A.ADR_ADRESSE1,
      A.ADR_ADRESSE2,
      A.etc...
    FROM
      T_CONTACTS_ADRESSES CA
      JOIN
      T_ADRESSES A
        ON
        CA.ADR_ID = A.ADR_ID;
    De cette façon, je peux afficher les adresses liées à un contact.
    Seulement, si je veux lier une adresse existante au contact, je n'ai théoriquement qu'à ajouter une ligne dans la table T_CONTACTS_ADRESSES avec les PK qui vont bien, la suite de la vue devrait s'afficher directement puisque directement issue de T_ADRESSES.
    Or, si je n'ajoute que CONT_ID et ADR_ID, le reste ne s'affiche pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    ClientDataSet4.Append;
    ClientDataSet4ADR_ID.Value := anAdresse.ID;
    ClientDataSet4CONT_ID.Value := FContactID;
    ClientDataSet4.Post;
    Donc je me pose 2 questions:

    1. la méthode Append ajoute une nouvelle ligne uniquement sur la table T_CONTACTS_ADRESSES ou sur T_ADRESSES aussi ?
    2. Comment ajouter simplement cette liaison et faire en sorte qu'elle s'affiche directement sans appliquer les changements (ApplyUpdates) pour éventuellement annuler les changements ?

    Merci d'avance
    Pedro
    Aucune réponse aux sollicitations techniques par MP

    Faut pas attendre d'en avoir besoin pour s'en servir... (Lucien Stéphane)

    Les pages Source C'est bon. Mangez-en!
    Le défi Delphi
    Règles du forum - FAQ Delphi - Pensez au chtit
    Aéroclub Bastia Saint-Exupéry

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 426
    Points : 24 790
    Points
    24 790
    Par défaut
    ClientDataSet4 contient le résultat du SQL fourni ?
    Si tu change juste le contenu, cela ne va pas rafraichir le reste

    Le Append ajoute toutes les colonnes du DataSet, peu importe l'origine de la colonne, oublie la notion de table à ce moment là !

    Par contre la mise à jour via ApplyUpdates ne sait pas forcément comment traiter la suite,
    en BDE\IBX, tu avais un TUdapteSQL pour fournir les SQL,
    en ADO, tu as 'Unique Table'
    en DBX, je ne l'ai expérimenté qu'une fois, le TDataSetProvider.BeforeUpdateRecord pour écrire tes propres SQL répartissant les données dans les différentes tables (surtout si cela peut impliquer des UPDATE et INSERT mélangés)

    En DBX sur ASA SQL Anywhere 10, grosse difficulté pour gérer le AutoInc déclaré en Required car PK NOT NULL mais AUTOINC, délire !

    Du coup, mon prédécesseur a mis en place une couche qui utilise des template (fichier ini) SQL UPDATE ou INSERT qui utilise les valeurs du TSimpleDataSet,
    le tout lié à un écran, oui oui, le plus "anti-MVC" que possible, sachant que si plusieurs écrans mettent à jour la même table,
    tu as autant de requête que d'écran
    sans parler de la validation de cohérence de données géré par l'écran, donc copier-merder un peu partout

    Moi, j'en ai eu marre d'écrire tous ces SQL dans des fichiers ini, j'ai fait un générateur de SQL via RTTI sur des objets métiers séparés de mes IHM.

    Et comme toi, j'ai aussi des Relation via ForeignKey, j'ai tout simplement un objet abstrait qui se divise en deux branches pour le moment :
    - ceux en PK AutoInc
    - ceux en PK composé de FK

    Normalement ApplyUpdates n'est pas obligatoire
    tu peux faire un tas de Append\Post sur ton CDS, ils resteront en local (peut-être voir ChangeLog à ce sujet)

    Je suppose aussi que tu as des MasterField, MasterSource pour que les DBControls de la vue directement issue de T_ADRESSES. soit rafraichi au modification de la jointure ?
    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
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Salut Shai
    Citation Envoyé par ShaiLeTroll Voir le message
    ClientDataSet4 contient le résultat du SQL fourni ?
    Oui, le TSQL Query ne faisant qu'une SELECT * FROM V_BIDULE...
    Citation Envoyé par ShaiLeTroll Voir le message
    Le Append ajoute toutes les colonnes du DataSet, peu importe l'origine de la colonne, oublie la notion de table à ce moment là !
    OK Ca ne m'arrange pas du tout ça...
    Citation Envoyé par ShaiLeTroll Voir le message
    en DBX, je ne l'ai expérimenté qu'une fois, le TDataSetProvider.BeforeUpdateRecord pour écrire tes propres SQL répartissant les données dans les différentes tables (surtout si cela peut impliquer des UPDATE et INSERT mélangés)
    Normalement, dans ce cas, c'est uniquement un INSERT simple. Le problème, c'est que si je touche au TDataSetProvider, je perds la possibilité d'annuler mes changements... Et il faut absolument que ce soit possible.

    D'après ce que j'ai compris, le TClientDataSet a un image en mémoire de la vue/requête/table issue de son DataSetprovider. Tant qu'on n'a pas appelé ApplyUpdates, la mise à jour "en dur" ne se fait pas.
    Ce TClientDataSet est attaché à un TDataSource qui est lui-même associé à un TDBGrid qui m'affiche les adresses.
    Du coup, si j'ajoute un nouveau TClientDataSet pour faire mon ajout, celui qui est associé au TDBGrid ne verra pas les modifications. A moins que je m'y prenne comme un pieds...
    Citation Envoyé par ShaiLeTroll Voir le message
    Je suppose aussi que tu as des MasterField, MasterSource pour que les DBControls de la vue directement issue de T_ADRESSES. soit rafraichi au modification de la jointure ?
    Ah bah non tiens... Je vais me renseigner sur ces MasterMachins...

    Merci pour ta réponse
    Pedro
    Aucune réponse aux sollicitations techniques par MP

    Faut pas attendre d'en avoir besoin pour s'en servir... (Lucien Stéphane)

    Les pages Source C'est bon. Mangez-en!
    Le défi Delphi
    Règles du forum - FAQ Delphi - Pensez au chtit
    Aéroclub Bastia Saint-Exupéry

  4. #4
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Bon, de ce que j'ai vu, je ne vois pas comment les propriétés MasterMachins pourraient m'aider...
    J'ai oublié de dire que je débute en SGBD et il y a encore beaucoup de notions que je ne maîtrise absolument pas...
    Pedro
    Aucune réponse aux sollicitations techniques par MP

    Faut pas attendre d'en avoir besoin pour s'en servir... (Lucien Stéphane)

    Les pages Source C'est bon. Mangez-en!
    Le défi Delphi
    Règles du forum - FAQ Delphi - Pensez au chtit
    Aéroclub Bastia Saint-Exupéry

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 426
    Points : 24 790
    Points
    24 790
    Par défaut
    Citation Envoyé par Pedro Voir le message
    Oui, le TSQL Query ne faisant qu'une SELECT * FROM V_BIDULE...
    Oui avec une jointure ?

    Citation Envoyé par Pedro Voir le message
    OK Ca ne m'arrange pas du tout ça...
    Comme tu l'évoques, le TClientDataSet a un image en mémoire, cela ajoute des NULL par défaut dans les colonnes non renseigné de DataSet, normalement, cela ne devrait pas te poser problème

    Citation Envoyé par Pedro Voir le message
    Ah bah non tiens... Je vais me renseigner sur ces MasterMachins...
    oubli, les Master, en Query ça passera pas sur une relation n-n si tu veux faire plusieurs insertions d'un seul coup, en Table+Filter, tu aurais pu te débrouiller mais c'était pour BDE+Paradox, à éviter avec FireBird (question de perf, volumétrie, réseau...)


    Tu es sur une fiche d'un T_CONTACTS, sur un seul ID de T_CONTACTS
    Tu veux lui associer 0 à n T_ADRESSES

    Contrainte : tu veux ajouter plusieurs contacts d'un coup en mémoire mais pouvoir annuler l'ensemble ?
    Tu confirmes ?
    C'est effectivement plus pénible, qu'un ajout un par un, où tu n'aurais aucun effort à fournir puisque la DB serait rempli donc un Refresh serait suffisant

    Ton problème, c'est que lorsque tu ajoutes un T_CONTACTS_ADRESSES, tu n'ajoutes que CONT_ID et ADR_ID
    Ton DBGrid n'a pas les données provenant de T_ADRESSES, ce qui est tout à fait logique puisqu'il affiche juste l'image en mémoire + un ligne contenant CONT_ID et ADR_ID, tout le reste est à nul !

    Une solution un peu simpliste, serait d'utiliser un AutreQuery, qui irait extraire les colonnes nécessaire pour l'affichage

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ClientDataSet4.Append;
    ClientDataSet4ADR_ID.Value := anAdresse.ID;
    ClientDataSet4CONT_ID.Value := FContactID;
     
    ClientDataSet4ADR_ADRESSE1.Value := AutreQueryADR_ADRESSE1.Value;
    ClientDataSet4ADR_ADRESSE2.Value := AutreQueryADR_ADRESSE2.Value;
    ClientDataSet4.Post;

    Après, il y a les Transactions !
    tant que le COMMIT n'est pas fait
    les données ne sont pas vraiment en DB, si tu fais un ROLLBACK cela annule les modifs, c'est peu comme second couche de mise en mémoire des données

    D'après ce que j'ai vu ApplyUpdate utilise une transaction, faudrait voir si l'on peut la conserver "ouverte", envoyer des données sans qu'il fasse le COMMIT et ainsi se laisser la possibilité de faire un ROLLBACK manuel

    Si on ne peut pas bidouillé la transaction du ApplyUpdate, tu peux faire tes propres SQL et gérer cela manuellement !
    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

  6. #6
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Oui avec une jointure ?
    La jointure est dans la vue telle que je l'ai décrite dans mon premier post
    Citation Envoyé par ShaiLeTroll Voir le message
    Contrainte : tu veux ajouter plusieurs contacts d'un coup en mémoire mais pouvoir annuler l'ensemble ?
    Tu confirmes ?
    Non, seulement un lien Contact - Adresse. Et un par un.
    Citation Envoyé par ShaiLeTroll Voir le message
    C'est effectivement plus pénible, qu'un ajout un par un, où tu n'aurais aucun effort à fournir puisque la DB serait rempli donc un Refresh serait suffisant
    Justement, cela ne suffit pas: Refresh ne fait rien du tout
    Citation Envoyé par ShaiLeTroll Voir le message
    Une solution un peu simpliste, serait d'utiliser un AutreQuery, qui irait extraire les colonnes nécessaire pour l'affichage
    Oui j'avais pensé faire des Champs calculés mais je cherche une méthode plus élégante
    Citation Envoyé par ShaiLeTroll Voir le message
    Après, il y a les Transactions !
    tant que le COMMIT n'est pas fait
    les données ne sont pas vraiment en DB, si tu fais un ROLLBACK cela annule les modifs, c'est peu comme second couche de mise en mémoire des données
    Certes, mais il faudrait que je revoies pas mal mon code du coup avec ça...
    Citation Envoyé par ShaiLeTroll Voir le message
    D'après ce que j'ai vu ApplyUpdate utilise une transaction, faudrait voir si l'on peut la conserver "ouverte", envoyer des données sans qu'il fasse le COMMIT et ainsi se laisser la possibilité de faire un ROLLBACK manuel
    Ah! Ca effectivement, ça pourrait être très intéressant ! Je vais me pencher là-dessus.
    Citation Envoyé par ShaiLeTroll Voir le message
    Si on ne peut pas bidouillé la transaction du ApplyUpdate, tu peux faire tes propres SQL et gérer cela manuellement !
    Oui tout à fait Mais encore une fois, je cherche à utiliser une méthode élégante
    Pedro
    Aucune réponse aux sollicitations techniques par MP

    Faut pas attendre d'en avoir besoin pour s'en servir... (Lucien Stéphane)

    Les pages Source C'est bon. Mangez-en!
    Le défi Delphi
    Règles du forum - FAQ Delphi - Pensez au chtit
    Aéroclub Bastia Saint-Exupéry

  7. #7
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Je suis en train de faire des tests sur une configuration Maitre-Détail et je pense que ça peut marcher si je m'y prends bien.
    Je pense que je m'y suis mal pris dès le départ...
    Pedro
    Aucune réponse aux sollicitations techniques par MP

    Faut pas attendre d'en avoir besoin pour s'en servir... (Lucien Stéphane)

    Les pages Source C'est bon. Mangez-en!
    Le défi Delphi
    Règles du forum - FAQ Delphi - Pensez au chtit
    Aéroclub Bastia Saint-Exupéry

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 426
    Points : 24 790
    Points
    24 790
    Par défaut
    Citation Envoyé par Pedro Voir le message
    Oui tout à fait Mais encore une fois, je cherche à utiliser une méthode élégante
    Elégance et Base de Données ! un Paradoxe !

    Citation Envoyé par Pedro Voir le message
    Je suis en train de faire des tests sur une configuration Maitre-Détail et je pense que ça peut marcher si je m'y prends bien.
    Je pense que je m'y suis mal pris dès le départ...
    Tout dépend de l'ergonomie que l'on souhaite, parfois des choses simples à première vue se montre ambitieuse à réaliser avec les composants DB qui ne sont pas toujours très pratique, surtout pour le Many-to-Many
    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

  9. #9
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Elégance et Base de Données ! un Paradoxe !
    J'y crois, tout est possible, tout est réalisable!
    Citation Envoyé par ShaiLeTroll Voir le message
    Tout dépend de l'ergonomie que l'on souhaite, parfois des choses simples à première vue se montre ambitieuse à réaliser avec les composants DB qui ne sont pas toujours très pratique, surtout pour le Many-to-Many
    Oui mais comme je te disais, je ne maîtrise pas beaucoup le dev avec BDD en général. Je découvre au fur et à mesure ce qui est simple et ce qui ne l'est pas

    Merci en tout cas pour tes réponses !
    Je pense que je peux passer en résolu
    Pedro
    Aucune réponse aux sollicitations techniques par MP

    Faut pas attendre d'en avoir besoin pour s'en servir... (Lucien Stéphane)

    Les pages Source C'est bon. Mangez-en!
    Le défi Delphi
    Règles du forum - FAQ Delphi - Pensez au chtit
    Aéroclub Bastia Saint-Exupéry

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 10/12/2006, 17h47
  2. bouton qui ajoute un enregistrement dans une table
    Par petitours dans le forum Access
    Réponses: 1
    Dernier message: 06/12/2006, 14h33
  3. Copie enregistrement sur une table access
    Par sgai2 dans le forum Access
    Réponses: 2
    Dernier message: 24/03/2006, 14h42
  4. Réponses: 2
    Dernier message: 08/02/2006, 22h22
  5. Réponses: 3
    Dernier message: 01/12/2005, 11h17

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