Announcement

Collapse
No announcement yet.

Problem mit 'ADODataSet.LoadFromFile'

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

  • Problem mit 'ADODataSet.LoadFromFile'

    Ich verwende MS-SQL-Server 7.0 und habe bei folgender Sequenz ein Problem:

    1. ADODataSet.SaveToFile('Test')

    2. Ändern von Daten in ADODataSet

    3. ADODataSet.LoadFromFile('Test')

    Nun erscheinen wieder die ursprünglichen Daten (In einem DBGrid).

    Nach einem Neustart des Programms erscheinen allerdings immer die geänderten Daten.

    Wo liegt das Problem?

  • #2
    Hallo,

    so richtig verstehe ich die Frage nicht. Wenn die Anwendung mit SaveToFile die Datenmenge in einer Datei abspeichert, macht sie einen Schnappschuss des aktuellen Datenbestands. Der Anwender ändert nun die Daten. Wird das Programm beendet und neu gestartet, holt sich TADODataSet erneut die Datenmenge vom SQL-Server, so dass die vorherigen Änderungen sichtbar sein müssen. Nur dann, wenn man über LoadFromFile den "alten Schnappschuss" wieder einliest, ist der ungeänderte Datenbestand sichtbar

    Comment


    • #3
      Hallo, Herr Kosch,

      vielen Dank für Ihre rasche Antwort.

      Mein Problem ist, das der 'alte Schnappschuss' nach dem Aufruf LoadFromFile zwar korrekt angezeigt wird, aber nicht permanent wird.

      Nach Neustart des Programmes (es genügt auch ein Schliessen und Öffenen des Formulars) ist immer der Datenbestand von vor LoadFromFile vorhanden. Alle Änderungen, die nach LoadFromFile gemacht werden, gehen ebenfalls verloren.

      Offenbar werden die Daten nicht auf die Festplatte zurückgeschrieben.

      Woran kann das liegen

      Comment


      • #4
        Hallo,

        das ist das von Microsoft dokumentierte Verhalten. Die Änderungen am RecordSet werden erst dann in die Datei übernommen, wenn <b>SaveToFile</b> aufgerufen wird. ADO unterstützt das Briefcase-Modell, bei dem man Änderungen zuerst in die Datei schreibt (Bsp: Notebook hat keine Verbindung zum Netz), um erst später ein Abgleich mit der SQL-Datenbank (Bsp: Notebook ist am Netz) zu machen. Wird über <i>LoadFromFile</i> die Datenmenge aus der Daten geladen und eine Verbindung zur Datenbank hergestellt, so gehen alle Änderungen zur Datenbank (aber nicht in die Datei)

        Comment


        • #5
          Herr Kosch,
          ich glaube wir reden aneinander vorbei. Das Modell habe ich schon verstanden.

          Mein Problem ist, dass die Änderungen nicht in die Datenbank gehen.

          Mit LoadFromFile werden die Daten korrekt aus einer Datei in das ADODataSet geladen. Man kann nun wieder alles mit den Daten machen (Open, Close, ändern usw. ...).
          Die geänderten Daten sind aber noch nicht in der Datenbank! Man kann das mit dem SQL Server Enterprise Manager kontrollieren.
          Ab dem Zeitpunkt des Aufrufes von LoadFromFile geht NICHTS mehr in die Datenbank zurück!!!
          In der Datenbank bleibt der Zustand von VOR LoadFrom File. Woran kann das liegen

          Comment


          • #6
            Hallo,

            als Zusammenfassung führe ich nochmals die Checkliste auf, die für diese Betriebsart eingehalten werden muss: <br>
            1. TADODataSet-Instanz: CursorLocation: <b>clUseClient</b> <br>
            2. TADODataSet-Instanz: LockType: <b>ltBatchOptimistic</b> <br>
            3. TADODataSet-Instanz: Active := True; //Daten vom SQL-Server holen <br>
            4. TADODataSet-Instanz: Connection := <b>nil</b>; // Datenbankverbindung abkoppeln <br>
            5. TADODataSet-Instanz: <b>SaveToFile</b> <br>
            6. TADODataSet-Instanz: Active := False; // Optional, zum Test schliessen <br>
            7. TADODataSet-Instanz: <b>LoadFromFile</b> <br>
            8. TADODataSet-Instanz: Daten ändern, posten <br>
            9. TADODataSet-Instanz: Connection := <b>ADOConnection1</b>; // Datenbankverbindung anflanschen <br>
            10. TADODataSet-Instanz: <b>UpdateBatch(arAll)</b>;<br>
            11. TADODataSet-Instanz: Zum Test schliessen <br>
            12. TADODataSet-Instanz: Zum Test neu öffnen -> aktualisierte Daten vom SQL-Server abholen (Änderungen vom Schritt 8 sind vorhanden)

            In einem Beispielprojekt (das auch eine automatische Konfliktauflösung implementiert) sieht das so aus:
            <pre>
            { ************************************************** **************
            Autor : Andreas Kosch
            Compiler : Delphi 6.0 Enterprise
            Betriebssystem : Windows 2000 SP2
            Erstellt am : 28.07.2001
            Beschreibung : ltBatchOptistic, Konfliktauflösung
            UnderlyingValue, OriginalValue
            ************************************************** ************** }

            unit UpdateConflictFrm;

            interface

            uses
            Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
            Dialogs, StdCtrls, ExtCtrls, DBCtrls, Grids, DBGrids, DB, ADODB, ComCtrls;

            type
            TFormMain = class(TForm)
            StatusBar1: TStatusBar;
            ADOConnection1: TADOConnection;
            ADODataSetCustomer: TADODataSet;
            ButtonGet: TButton;
            ButtonUpdateBatch: TButton;
            DataSourceCustomer: TDataSource;
            ADODataSetCustomerCustID: TAutoIncField;
            ADODataSetCustomerCustName: TStringField;
            DBGrid1: TDBGrid;
            DBNavigator1: TDBNavigator;
            MemoLog: TMemo;
            ButtonCheck: TButton;
            ButtonResync: TButton;
            procedure ButtonGetClick(Sender: TObject);
            procedure ButtonUpdateBatchClick(Sender: TObject);
            procedure ADOConnection1AfterConnect(Sender: TObject);
            procedure ADOConnection1AfterDisconnect(Sender: TObject);
            procedure ADOConnection1InfoMessage(Connection: TADOConnection;
            const Error: Error; var EventStatus: TEventStatus);
            procedure ADODataSetCustomerAfterOpen(DataSet: TDataSet);
            procedure ADODataSetCustomerAfterPost(DataSet: TDataSet);
            procedure ADODataSetCustomerAfterRefresh(DataSet: TDataSet);
            procedure ButtonCheckClick(Sender: TObject);
            procedure ADODataSetCustomerAfterClose(DataSet: TDataSet);
            procedure ButtonResyncClick(Sender: TObject);
            private
            { Private-Deklarationen }
            public
            { Public-Deklarationen }
            end;

            var
            FormMain: TFormMain;

            implementation

            {$R *.dfm}

            uses ADOInt;

            {
            Schritt 1: Daten von der SQL Server 2000-Datenbank abfordern
            und als lokales RecordSet-Objekt verwalten.
            Die TADODataSet-Datenmenge ist unabhängig, die Verbindung
            kann daher getrennt werden, ohne das die Datenmenge
            dabei automatisch geschlossen wird.
            (LockType = ltBatchOptimistic)
            }

            procedure TFormMain.ButtonGetClick(Sender: TObject);
            begin
            ADOConnection1.Connected := True;
            with ADODataSetCustomer do
            begin
            Connection := ADOConnection1;
            Active := True; // Daten abholen
            Connection := nil; // Datenbankverbindung abkoppeln
            end;
            ADOConnection1.Connected := False;
            end;

            {
            Schritt 2: Alle Änderungen, die der Anwender in der Zwischenzeit
            vorgenommen hat, sollen in der SQL Server 2000-Datenbank
            eingetragen werden:
            a) ADO-Verbindung herstellen
            b) UpdateBatch aufrufen
            c) ADO-Verbindung trennen.
            }

            procedure TFormMain.ButtonUpdateBatchClick(Sender: TObject);
            begin
            ADOConnection1.Connected := True;
            with ADODataSetCustomer do
            begin
            Connection := ADOConnection1;
            UpdateBatch(arAll);
            Active := False;
            Connection := nil;
            end;
            ADOConnection1.Connected := False;
            end;

            {
            Zwischenschritt: Der Anwender kann jederzeit prüfen, wie das native
            RecordSet-Objekt (ADO) die Daten verwaltet:
            a) UnderlyingValue
            b) OriginalValue
            Der Aufruf von UpdateCursorPos synchronisiert dabei
            TADODataSet (ADO Express) mit RecordSet (ADO)
            }

            procedure TFormMain.ButtonCheckClick(Sender: TObject);
            resourcestring
            cFmt = 'UnderlyingValue: »%s« OriginalValue: »%s«';
            begin
            with ADODataSetCustomer do
            begin
            UpdateCursorPos;
            with RecordSet.Fields[1] do
            begin
            MemoLog.Lines.Add(Format(cFmt, [UnderlyingValue,
            OriginalValue]));
            if UnderlyingValue <> OriginalValue then
            ShowMessage('Konflikt entdeckt!');
            end;
            end;
            end;

            {
            Zwischenschritt: ADO soll für seine Daten die aktuell im originalen
            Datenbestand vorgefundenen Werte als eigene
            Vergleichswerte nutzen. Nach diesem Aufruf ist
            der 2. UpdateBatch-Aufruf auch im vorherigen
            Konfliktfall erfolgreich.
            }

            procedure TFormMain.ButtonResyncClick(Sender: TObject);
            begin
            ADOConnection1.Connected := True;
            with ADODataSetCustomer do
            begin
            Connection := ADOConnection1;
            RecordSet.Resync(adAffectAll, adResyncUnderlyingValues);
            Connection := nil;
            UpdateCursorPos;
            end;
            MemoLog.Lines.Add('TADOConnection.RecordSet.Resync ');
            ADOConnection1.Connected := False;
            end;

            procedure TFormMain.ADOConnection1AfterConnect(Sender: TObject);
            begin
            MemoLog.Lines.Add('TADOConnection: Connect');
            end;

            procedure TFormMain.ADOConnection1AfterDisconnect(Sender: TObject);
            begin
            MemoLog.Lines.Add('TADOConnection: Disconnect');
            end;

            procedure TFormMain.ADOConnection1InfoMessage(Connection: TADOConnection;
            const Error: Error; var EventStatus: TEventStatus);
            begin
            MemoLog.Lines.Add('TADOConnection: InfoMessage');
            end;

            procedure TFormMain.ADODataSetCustomerAfterOpen(DataSet: TDataSet);
            begin
            MemoLog.Lines.Add('TADODataSet: AfterOpen');
            ButtonCheck.Enabled := True;
            end;

            procedure TFormMain.ADODataSetCustomerAfterPost(DataSet: TDataSet);
            begin
            MemoLog.Lines.Add('TADODataSet: AfterPost');
            end;

            procedure TFormMain.ADODataSetCustomerAfterRefresh(DataSet: TDataSet);
            begin
            MemoLog.Lines.Add('TADODataSet: AfterRefresh');
            end;

            procedure TFormMain.ADODataSetCustomerAfterClose(DataSet: TDataSet);
            begin
            MemoLog.Lines.Add('TADODataSet: AfterClose');
            ButtonCheck.Enabled := False;
            end;

            end.
            </pre>
            &#10

            Comment

            Working...
            X