Announcement

Collapse
No announcement yet.

oldvalue ohne cashed Update?

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

  • oldvalue ohne cashed Update?

    Hallo,

    ich habe eine grössere Anwendung von BDE auf ADO umgestellt. Aufgrung der Menge an Tabeln und Querys habe ich TAdoTable und TAdoQuery verwendet.

    Vorher habe ich Änderungen (Alt/Neu) über oldvalues/Newvalues protokolliert. Ging natürlich nur mit Cashed Updates=true.

    Bei den Ado-Komps gibt es leider diese Eigenschaft nicht, daher bleibt der Oldvalue leer.

    Was kann ich am einfachsten machen?

    Viele Grüsse
    Mathias

  • #2
    Hallo,

    >..TAdoTable und TAdoQuery .. mit Cashed Updates=true.

    in diesem Fall hat die Bequemlichkeit selbstverständlich ihren Preis :-)

    Wenn das Recordset-Objekt von ADO im ltBatchOptimistic-Modus betrieben wird, stehen die Vorher-/Nachher-Daten über die Eigenschaften <b>UnderlyingValue</b> und <b>OriginalValue</b> zur Verfügung. Ich kann nur mit einem Beispiel für <b>TADODataSet</b> dienen, das aus meinem <i>ADO und Delphi</i>-Buch stammt:
    <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&gt

    Comment


    • #3
      Hallo Herr Kosch,

      danke für die Info.
      Muss ich wohl noch ein bischen weiter umstellen.

      Mathia

      Comment


      • #4
        Dazu noch eine Frage:

        wenn ich schon nochmal ran muss, sollte ich vielleicht gleich die TBetterAdoDatasets verwenden (wird Access mdb) oder gibt es da beim Protokollieren auch noch Probleme?
        Zur erleichterung der Umstellungsarbeit habe ich mir ein Tool geschrieben, dass die Dfms in Text umwandelt dort macht das Tool die Anpassungen und konvertiert wieder zurück. Die Pas-Dateien werden auch angepasst. Ging damit so einigermassen einfacher.
        Hat evtl jemand schon so etwas entwickelt, dass auf Datasets umstellen kann?

        Viele Grüsse

        Mathia

        Comment

        Working...
        X