Announcement

Collapse
No announcement yet.

Format von ClientDataSet.Delta?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Format von ClientDataSet.Delta?

    Hallo,

    kennt irgendwer das Format von ClientDataSet.Delta, oder hat eine URL wo es beschrieben wird. Hinter dem OleVariant kann ja ne ganze Menge stehen.

    Es wäre zum protokolieren ausgesprochen praktisch, wenn man da dran käme.

    p.s. Trigger auf jeder Tabelle wäre eine unpraktische Lösung.

    Danke schon mal

    Andreas

  • #2
    Hallo Andreas,

    wenn bei einer TClientDataSet-Instanz die Eigenschaft <b>IndexFieldName</b> auf den Wert <b>CHANGEINDEX</b> gesetzt wird, zeigt das ClientDataSet alle nach dem letzten Aufruf von MergeChangeLog geänderten Datensätze an. Dabei wird der alte und der neue Zustand als separate Datensätze aufgelistet

    Comment


    • #3
      Hallo Andreas,

      Danke für die schnelle Antwort, auf Dich hatte ich gehofft. Aber wo hast Du das her? In der OnLine Hilfe steht es nicht.

      Andrea

      Comment


      • #4
        Hallo Andreas,

        derartige Schätze findet man beim Wühlen in den VCL-Sourcen. In der Unit <i>DSIntf.pas</i> werden die Zeichenketten definiert, die in <i>DBClient.pas</i> intern verwendet werden. Allerdings hat ein TClientDataSet nichts dagegen, dass man selbst diese Fähigkeiten anfordert

        Comment


        • #5
          Hallo Andreas,

          da Du die Sourcen so gut kennst, hake ich noch mal nach.

          Ich jabe zwei ClientDataSet auf der Form, die zwei Tabellen betreffen die über referentielle Integrität verbunden sind.

          Mache ich
          <pre>CDSMaster.ApplyUpdates
          CDSDetail.ApplyUpdates</pre>

          dann knallt es bei Löschungen im Detail und umgekehrt bei Einfügungen im Master.

          Optimal wäre
          <pre>CDSMaster.ApplyInsert&Updates
          CDSDetail.ApplyAll
          CDSMaster.ApplyDeletes</pre>

          Hast Du eine Idee

          Comment


          • #6
            Hallo Andreas,

            für Master/Detail-Datenmengen gibt es prinzipiell 2 Alternativen:

            1. Nested Datasets - ab Delphi 4 stehen diese eingebetteten Datenmengen zur Verfügung. Für den Updateprozess ist keine Sonderbehandlung notwendig.

            2. Programmgesteuerte Behandlung der 2 beteiligten Delta-Datenmengen.
            Ein Beispiel dafür hat Dan Miser in seinem Artikel "<i>ClientDataset as a Replacement for Cached Updates</i>" (Borland Conference 1999) vorgestellt. Ein möglicher Weg ist das Austauschen der Reihenfolge in Abhängigkeit von der durchzuführenden Aktion:
            <pre>
            procedure TForm1.DetailBeforeClose(DataSet: TDataSet);
            begin
            if Master.UpdatesPending or Detail.UpdatesPending then
            if Master.UpdateStatus = usInserted then
            Database1.ApplyUpdates([Master, Detail]) else
            Database1.ApplyUpdates([Detail, Master])
            end;
            </pre>
            Bei anderen Beispielen wird <b>BeforeUpdateRecord</b> des Providers genutzt, um datensatzbezogen Anpassungen vornehmen zu können. Ich nutze in meinem Anwendungen ebenfalls diesen flexiblen Weg aus - wobei das zum Beispiel so aussehen könnte:
            <pre>
            procedure TRemoteDataModule1.Provider1BeforeUpdateRecord(Sen der: TObject; SourceDS: TDataSet;
            DeltaDS: TClientDataSet; UpdateKind: TUpdateKind; var Applied Boolean);
            begin
            if UpdateKind = ukDelete then
            begin
            Query1.SQL.Text := 'UPDATE Customer SET Status = "DEL" WHERE Id = :ID';
            Query1.Params[0].Value := SourceDS.FieldByName('ID').Value;
            Query1.ExecSQL;
            Applied := True
            end;
            ...
            end;
            </pre>
            Da man für jeden betroffenen Datensatz UpdateKind ermitteln kann, ist auch der Aufruf von Stored Procedures der Datenbank möglich, um Datensätze einzufügen, zu aktualisieren oder zu löschen

            Comment


            • #7
              Hallo Andreas

              Der Hinweis mit ProviderBeforeUpdate ist nicht schlecht, hilft beim einarbeiten, trifft aber eigentlich nicht ganz, da ich die Reihenfolge in der die Updates vorgenommen werden, verändern will.

              Ich könnte zwar in BeforeUpdate die Keys speichern, die später gelöscht werden sollen, aber dann wird es mit den Fehlerfällen recht kompliziert.

              Deine oben beschriebene Anwendung, läßt sich meiner Ansicht nach (zumindestens bei InterBase) leichter realisieren, wenn hinter dem Provider ein TIBDataSet steht und dort ein Modify, Insert und DeleteQuery hinterlegt wird. Dann nach ResolveToDataSet = true und du kannst mit deinen hinterlegen SQL Statement Arbeiten. Mit einem UpdateSQL sollte das auch gehen, wenn kein TIBDataSet zur Verfügung steht

              Comment


              • #8
                Hallo Andreas,

                in der Tat hat jeder Automatismus so seine Beschränkungen. Wenn Du die Reihenfolge der Datensatz-Aktualisierungen verändern willst, wird es das Beste sein, ganz auf diesen Automatismus (ApplyUpdates oder BeforeUpdate) zu verzichten und direkt auf die Datensätze des Deltas zuzugreifen. Das ist spätestens dann sinnvoll, wenn mit NULL-Werten beim UPDATE hantiert werden muss oder beim INSERT die in der Datenbank hinterlegten DEFAULTs ausgenutzt werden sollen. In diesen Fällen muss die SQL angepasst werden. Daher greife ich in Anwendungen gerne auf Stored Procedures zurück, die beim INSERT/UPDATE alle Daten über Parameter erhalten und intern die notwendigen Anpassungen/Prüfungen übernehmen

                Comment


                • #9
                  Danke für die Hilfe, werde mir was überlegen und die Ergebnisse auch hier posten.

                  Was lehrt uns das?

                  Automatismen sind nur solange gut, bis man auf eine ernsthafte Anwendung trifft.

                  p.s. Weißt Du wo was zu Nested Tables, bei ClientDataSet beschrieben ist

                  Comment


                  • #10
                    Hallo Andreas

                    meine Versuche mit dem <b>DataSetField</b> sind irgendwie nicht erquickend. Auch in CodeZentral und Community habe ich nix gefunden.

                    Hast Du noch einen Hinweis, wie das funzt.

                    Dank

                    Comment


                    • #11
                      Hallo Andreas, Hallo Allerseits,

                      die Lösung des Problems inst tatsächlich TDataSetField und wie das genau geht steht im Thread zum TDataSetField. Danke an Rafel Coyle

                      Comment

                      Working...
                      X