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 :

TDBGrid: Les modifications ne s'enregistrent pas dans la base


Sujet :

Bases de données Delphi

  1. #1
    Membre à l'essai
    Homme Profil pro
    Retraité
    Inscrit en
    Janvier 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2006
    Messages : 20
    Points : 11
    Points
    11
    Par défaut TDBGrid: Les modifications ne s'enregistrent pas dans la base
    Bonjour,

    Je suis relativement nouveau dans l'utilisation des bases de données (INTERBASE) et je suis confronté à un problème que je n'arrive pas à résoudre.
    J'ai une TDBGrid liée à un TIBDataset.
    Je peux modifier les champs comme je le souhaite, mais lorsque je quitte la grille, les données reviennent à leurs états initiaux.
    Je n'arrive pas à enregistrer les modifications dans la base.
    Le SelectSQL est une jointure sur 3 tables avec 2 variables paramétrées.
    La grille travaille sur 4 champs de la table de plus bas niveau. Je les ai déclarés en champs persistants.
    CachedUpdate=true.
    Sur le OnExit de la grille, je fait un post, close, open->sans succès.
    Je force un commit->sans succès.

    Merci d'avance pour votre aide.

  2. #2
    Membre à l'essai
    Homme Profil pro
    Retraité
    Inscrit en
    Janvier 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2006
    Messages : 20
    Points : 11
    Points
    11
    Par défaut
    Bonjour,
    Une précision, le SelectSQL et
    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
    SELECT
    GEOM.IX_GEOM_BR,
    GEOM.NUMORDRE_D_USIN,
    GEOM.REPERE_ISO,
    GRP.IX_GEOM_BR,
    GRP.IX_GROUPE,
    GRP.NUMORDRE_DE_GROUPE,
    GRP.NBDENTS,
    PA.IX_PASPROGRESS,
    PA.IX_GROUPE,
    PA.NUMORDRE_INTERDENTS,
    PA.PAS,
    PA.PROGRESS
    FROM ( DENT_GEOMETRIEDENTURE GEOM LEFT JOIN DENT_GROUPES GRP ON
    GEOM.IX_GEOM_BR = GRP.IX_GEOM_BR )
    LEFT JOIN DENT_PASPROGRESS PA ON GRP.IX_GROUPE = PA.IX_GROUPE
    WHERE REPERE_ISO = :REPERE_ISO_ID 
    AND NUMORDRE_D_USIN = :NUMORDRE_D_USIN_ID 
    ORDER BY NUMORDRE_DE_GROUPE, NUMORDRE_INTERDENTS

  3. #3
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Bonjour

    Ton problème n'est pas directement lié à l'utilisation d'Interbase mais plutôt à celle du composant TIBDataSet.

    Ta question sera mieux placée par exemple dans le forum Delphi/Base de données si tu utilises cet EDI.

    Cependant, question: La propriété ModifySQL est-elle renseignée correctement ?
    (Ma question vaut également pour InsertSQL et DeleteSQL)

    @+ Claudius

  4. #4
    Membre à l'essai
    Homme Profil pro
    Retraité
    Inscrit en
    Janvier 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2006
    Messages : 20
    Points : 11
    Points
    11
    Par défaut
    Bonjour,
    A la question
    "La propriété ModifySQL est-elle renseignée correctement ?
    (Ma question vaut également pour InsertSQL et DeleteSQL)"
    Je pense que oui, mais le mieux est que vous vérifiez:
    ModifySQL ->
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    update DENT_PASPROGRESS
    set
      IX_GROUPE = :IX_GROUPE,
      IX_PASPROGRESS = :IX_PASPROGRESS,
      NUMORDRE_INTERDENTS = :NUMORDRE_INTERDENTS,
      PAS = :PAS,
      PROGRESS = :PROGRESS
    where
      IX_GROUPE = :OLD_IX_GROUPE and
      IX_PASPROGRESS = :OLD_IX_PASPROGRESS and
      NUMORDRE_INTERDENTS = :OLD_NUMORDRE_INTERDENTS and
      PAS = :OLD_PAS and
      PROGRESS = :OLD_PROGRESS
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    InsertSQL ->
    insert into DENT_PASPROGRESS
      (IX_GROUPE, IX_PASPROGRESS, NUMORDRE_INTERDENTS, PAS, PROGRESS)
    values
      (:IX_GROUPE, :IX_PASPROGRESS, :NUMORDRE_INTERDENTS, :PAS, :PROGRESS)

    DeleteSQL->
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    delete from DENT_PASPROGRESS
    where
      IX_GROUPE = :OLD_IX_GROUPE and
      IX_PASPROGRESS = :OLD_IX_PASPROGRESS and
      NUMORDRE_INTERDENTS = :OLD_NUMORDRE_INTERDENTS and
      PAS = :OLD_PAS and
      PROGRESS = :OLD_PROGRESS
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    RefreshSQL->
    Select 
      IX_PASPROGRESS,
      IX_GROUPE,
      NUMORDRE_INTERDENTS,
      PAS,
      PROGRESS
    from DENT_PASPROGRESS 
    where
      IX_GROUPE = :IX_GROUPE and
      IX_PASPROGRESS = :IX_PASPROGRESS and
      NUMORDRE_INTERDENTS = :NUMORDRE_INTERDENTS and
      PAS = :PAS and
      PROGRESS = :PROGRESS

    Au sujet du forum, effectivement je croyais avoir posté sur le forum de Delphi et BD et j'étais en consultation dessus (j'utilise DELPHI XE) , mais au dernier moment, j'ai consulté le message précédent que j'avais posté sur INTERBASE et j'ai démarré sur l'écriture de ce post dans la foulée. Désolé!
    Si c'est possible de le changer de place, il n'y a pas de problème.

    Merci encore pour cette première réponse.

  5. #5
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Je n'utilise plus les composants IBX depuis longtemps, mais en basculant CachedUpdate à False, qu'est-ce que cela donne ?

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    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 447
    Points : 24 849
    Points
    24 849
    Par défaut
    ou en appelant ApplyUpdates
    Autant c'est bien documenté avec le TBDEDataSet mais autant cela n'est pas clair pour le TIBCustomDataSet
    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

  7. #7
    Membre à l'essai
    Homme Profil pro
    Retraité
    Inscrit en
    Janvier 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2006
    Messages : 20
    Points : 11
    Points
    11
    Par défaut
    Avec le ApplyUpDates suivi de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    With IBTransaction1 do Commit;
    et avec CachedUdates à true, cela n'enregistre toujours rien.
    J'ai des TDBEdit sur la même fiche qui fonctionnent très bien.
    A chaque Evnt OnExit, j'ai leurs ai mis un Post suivi d'une requête pour réouvrir l'ensemble de données.
    Pour faire le parallèle, je ne vois pas précisément comment une grille sur un TIBDataset fonctionne.
    A chaque modif.de la donnée d'une cellule, il y a inscription en mémoire cache (on visualise la modification à l'écran), mais pas dans la base? Alors qu'a chaque modif. de donnée dans un TDBEdit, le post inscrit dans la base?
    Pour l'instant, j'en ai conclu que l'enregistrement dans la base doit se faire globalement et c'est pour cette raison que j'appelle les demandes d'enregistrement sur le OnExit de la grille.
    J'ai besoin d'un peu d'éclaircissement sur ce sujet.

  8. #8
    Membre à l'essai
    Homme Profil pro
    Retraité
    Inscrit en
    Janvier 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2006
    Messages : 20
    Points : 11
    Points
    11
    Par défaut
    Au sujet du CachedUpdate à False, en ne mettant plus rien sur le OnExit de la grille, il me semblait que cela fonctionnait. Les modif. restaient même en allant cliquer sur les TDBedit de la même fiche (avec le ApplyUpdates, la grille revient à son état initial dès que l'on a passé le OnExit de la grille).
    Mais... en changeant de fiche et en revenant sur cette dernière (=rappel du select...), les modif. ont disparues. Après vérif. avec la console INTERBASE, les modif. n'ont effectivement pas été enregistrées.

  9. #9
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    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 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Citation Envoyé par billbocquet Voir le message
    A chaque Evnt OnExit, j'ai leurs ai mis un Post suivi d'une requête pour réouvrir l'ensemble de données.

    C'est horrible, normalement, le Post doit être fait dans un bouton Valider explicite, le DataSet est capable de conserver en mémoire toutes les modifications (en plus la propriété modified indique justement si il y a eu modification, en jouant avec OldValue on peut savoir l'ancienne valeur)

    Tu utilise le même DataSource et le même DataSet pour l'ensemble : Grille + Edit dans cette forme ?

    Pense qu'il faut faire Edit (ou utiliser AutoEdit du DataSource) pour la grille soit en Edition.

    Citation Envoyé par billbocquet Voir le message
    A chaque modif.de la donnée d'une cellule, il y a inscription en mémoire cache (on visualise la modification à l'écran), mais pas dans la base?
    Heureusement !
    Imagine un écran avec 20 champs, tu ne vas pas faire l'écriture tout le temps, surtout en utilisation concurrentiel et multi-utilisateur !
    C'est Post() qui valide les données, et le mieux c'est que l'utilisateur soit conscient que le bouton OK valide les données et le bouton Cancel permet d'annuler la saisie
    Ensuite, tu as le Cache, qui permet de stocker plusieurs Post()
    En général, tu n'as que le record concerné par la fiche en cours (ou ceux présent dans le DBGrid)
    Personnellement mes DBGrid sont uniquement en visualisation, pour modifier un enregistrement, il y a un formulaire dédié (ShowModal), en général, si une seule table le Post() utilise une transaction implicite, si plusieurs tables, une transaction pour l'ensemble mais tout se déroule dans le bouton Valider de la fiche (du moins en réalité, cela appel la méthode Save d'un objet métier qui lui sait ce qu'il doit faire)

    Enfin, la transaction, imaginons que la saisie est sur un ensemble de tables, soit toutes les modifications passent soit aucune pour conserver un état cohérent à la donnée
    Ces mécanismes sont très importants !

    Citation Envoyé par billbocquet Voir le message
    Alors qu'a chaque modif. de donnée dans un TDBEdit, le post inscrit dans la base?
    TRES mauvaise pratique !

    Citation Envoyé par billbocquet Voir le message
    Pour l'instant, j'en ai conclu que l'enregistrement dans la base doit se faire globalement et c'est pour cette raison que j'appelle les demandes d'enregistrement sur le OnExit de la grille.
    Utilise un bouton "Valider" clair et explicite, tu vas perdre ton utilisateur avec un enregistrement automatique !
    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

  10. #10
    Membre à l'essai
    Homme Profil pro
    Retraité
    Inscrit en
    Janvier 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2006
    Messages : 20
    Points : 11
    Points
    11
    Par défaut
    Bonjour,

    D'abord, merci pour les éclaircissements.
    Pour ce qui est de
    Tu utilise le même DataSource et le même DataSet pour l'ensemble : Grille + Edit
    Non, Les Edit pointent vers un Dataset et la grille vers un autre. Les données entre les DataSet n'ont pas de relations directes.
    normalement, le Post doit être fait dans un bouton Valider explicite
    Mon donneur d'ordre prend sans arrêt comme exemple les applications du type Itune où l'on ne fait pas de [Ok] et encore moins de [Voulez-vous vraiment enregistrer les modifications] à tout bout de champ. Pour lui, cette manière de procéder, c'est de l'ancien temps. C'est pour me rappocher de sa manière de voir, que j'ai essayé de minimiser les boutons [valider] et [Confirmer].
    Il faut noter que l'appli que je lui fait est du type mono poste.
    Elle va servir à mémoriser le paramétrage des programmes ISO envoyés sur la machine outil devant laquelle l'appli va tourner.
    L'idée initiale, c'est une appli par machine implantée sur chaque PC qui est devant chaque machine.
    L'incidence de multi mise à jour due à plusieurs utilisateurs qui sont connectés en même temps sur la base ne devrait pas arriver dans mon cas.
    Je reconnais qu'écrire dans la base à chaque modif. de l'opérateur c'est pas terrible. Je vais reprendre ça.
    Pour ce qui est de l'enregistrement effectif dans la base, je ne pense pas que ça va changer quelque chose à mon problème.

  11. #11
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    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 447
    Points : 24 849
    Points
    24 849
    Par défaut
    InterBase Embedded, je suppose !
    Passe AutoCommit à True et CachedUpdate à False, en monoposte, tu peux te permettre d'y aller comme un bourrin !
    Tu as du te mélanger dans les DataSet, les transactions et tout ça !
    Tu as relu les SQL, seul DENT_PASPROGRESS est mis à jour, mais pas DENT_GROUPES ni DENT_GEOMETRIEDENTURE


    Citation Envoyé par billbocquet Voir le message
    Pour lui, cette manière de procéder, c'est de l'ancien temps.
    iTunes typiquement utilise son propre format de stockage et n'a aucune problématique d'accès concurrentiel ni de problématique réseau pour gérer les configurations locales
    Et les données gérés sont surement plus simple que tes données !

    Sinon, rien empêche de sauvegarder lors du OnClose de la Fiche
    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

  12. #12
    Membre à l'essai
    Homme Profil pro
    Retraité
    Inscrit en
    Janvier 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2006
    Messages : 20
    Points : 11
    Points
    11
    Par défaut
    Ca y est, tous fonctionne!
    Le problème venait que, dans les instructions de ModifySQL, InsertSQL, DeleteSQL et RefreshSQL, les champs à mettre à jour s'adressaient à deux tables différentes, deux des trois données dans la jointure.
    J'ai créé deux grilles à la place de l'unique qui existait. J'ai mis deux TIBDataSet et deux DataSourses liés à ces grilles.
    Les instructions SQL (ModifYSQL pour simplifier, les DeleteSQL,... sont dans le même schéma) sont:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    update DENT_GROUPES
    set
      IX_GEOM_BR = :IX_GEOM_BR,
      IX_GROUPE = :IX_GROUPE,
      NBDENTS = :NBDENTS,
      NUMORDRE_DE_GROUPE = :NUMORDRE_DE_GROUPE
    where
      IX_GROUPE = :OLD_IX_GROUPE
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    update DENT_PASPROGRESS
    set
      IX_GROUPE = :IX_GROUPE,
      IX_PASPROGRESS = :IX_PASPROGRESS,
      NUMORDRE_INTERDENTS = :NUMORDRE_INTERDENTS,
      PAS = :PAS,
      PROGRESS = :PROGRESS
    where
      IX_PASPROGRESS = :OLD_IX_PASPROGRESS
    Depuis, ça fonctionne et ça enregistre dans la base correctement.
    Pour la partie 'utilisation de la mémoire cache', j'ai mis tous les TDataSet liés à ce que je suis en train de traiter à J'ai reprogrammé pour valider les modifications par un bouton [Valider] ou ne pas valider par un bouton [Annuler] et ça fonctionne... et j'y trouve vraiment génial!
    Merci encore pour votre aide

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 21/06/2012, 23h23
  2. Réponses: 1
    Dernier message: 24/11/2011, 08h20
  3. Réponses: 10
    Dernier message: 14/02/2007, 12h03
  4. Réponses: 8
    Dernier message: 12/07/2006, 10h32
  5. Réponses: 4
    Dernier message: 02/06/2006, 12h03

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