Announcement

Collapse
No announcement yet.

Probleme beim Speichern mit TADODataset

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

  • Probleme beim Speichern mit TADODataset

    Hallo allerseits ...

    (MS SQL 2000 engl., ADO 2.7, D5 )

    bei mir tritt beim Speichern eines TADODatasets folgendes Problem auf / Fehlermeldung auf :

    "EOLException : Die zum Aktualisieren angegebene Zeile wurde nicht gefunden. Einige Werte wurden seit dem letzten Lesen ggf. geändert"

    Leider habe ich die Daten nach dem folgenden Prinzip geändert :

    Dataset.Edit
    .. tu was ...
    Dataset.Post

    und bei Dataset.Append und anschliessendem Dataset.Post erhalte ich allerdings eine andere Fehlermeldung : "EOLEExcption : Das Zeilenhandle bezog sich auf eine gelöschte oder zum Löschen markierte Zeile."

    Des weiteren hat dieses Dataset persistente Felder, die teilweise "calculated" sind. Ich konnte bereits alle Lookup-Felder eliminieren, weil diese ebenfalls zu Problemen führen.

    Hat Jemand eine Idee wie oder was ich da einstellen muss, damit der Post
    ohne die Exception läuft.

    Derzeit sind folgende Einstellungen eingestellt :
    CursorLocation := clUseClient
    CursorType := ctStatic (ctKeyset und ctDynamic habe ich auch versucht)
    LockType := ltOptimistic ...

    Danke vorab mal für eure Bemühungen

    Markus

    P.S. : ich setze bereits TBetterADODataSet 4.0.2 mit mehr oder weniger Erfolg ein

  • #2
    Hallo,

    das Recordset-Objekt von ADO muss alle vom Benutzer vorgenommene Aktionen automatisch in SQL-Anweisungen (UPDATE, INSERT, DELETE) übersetzen, wobei es bei diesem Job zwangsläufig Grenzen gibt. Da der MS SQL Server 2000 genutzt wird, liefert ein Blick auf die mitprotokollierten Logs des <i>Profilers</i> den Grund für diese Probleme.

    Wenn das Problem mit der "groben Kelle" gelöst werden soll, kann man auch zu drastischen Mitteln greifen:
    <pre>
    { ************************************************** **************
    Typ : Hauptformular
    Autor : Andreas Kosch
    Compiler : Delphi 5.01 Enterprise/Delphi 6.01 Enterprise
    Betriebssystem : Windows 2000 SP1 / Windows XP Professional
    Begonnen am : 14.01.2001
    Beschreibung : Update Criteria=adCriteriaKey sorgt im
    Multiuser-Betrieb dafür, das beim UPDATE als
    WHERE-Einschränkung nur der Primärschlüssel
    verwendet wird.
    Im Gegensatz daher sorgt adCriteriaAllCols
    dafür, dass die Exception "... Datensatz
    geändert..." erscheint.

    Achtung: Verwendet die SQL Server 2000-Datenbank OSSISOFT auf
    dem Server OSSISOFT-W2KSRV. Der ConnectionString muss
    vor dem Aufruf des Programms angepasst werden.
    ************************************************** ************** }

    unit UpdateCriteriaFrm;

    interface

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

    type
    TForm1 = class(TForm)
    StatusBar1: TStatusBar;
    ADOConnection1: TADOConnection;
    ADODataSet1: TADODataSet;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    ADODataSet1ID: TAutoIncField;
    ADODataSet1Name: TStringField;
    ADODataSet1Vorname: TStringField;
    ADODataSet1Ort: TStringField;
    ADODataSet1eMail: TStringField;
    DBNavigator1: TDBNavigator;
    RadioGroup1: TRadioGroup;
    procedure RadioGroup1Click(Sender: TObject);
    private
    { Private-Deklarationen }
    public
    { Public-Deklarationen }
    end;

    var
    Form1: TForm1;

    implementation

    {$R *.DFM}

    uses ADOInt;

    procedure TForm1.RadioGroup1Click(Sender: TObject);
    begin
    ADODataSet1.Active := False;
    case RadioGroup1.ItemIndex of
    0 : begin
    ADODataSet1.Active := False;
    ADOConnection1.Connected := False;
    end;
    1 : begin
    ADOConnection1.Connected := True;
    ADODataSet1.Active := True;
    with ADODataSet1.Recordset do
    begin
    Properties['Update Criteria'].Value := adCriteriaKey;
    Properties['Update Resync'].Value := adResyncAll;
    end;
    StatusBar1.SimpleText := 'Update Criteria=adCriteriaKey';
    end;
    2 : begin
    ADOConnection1.Connected := True;
    ADODataSet1.Active := True;
    with ADODataSet1.Recordset do
    begin
    Properties['Update Criteria'].Value := adCriteriaAllCols;
    Properties['Update Resync'].Value := adResyncAll;
    end;
    StatusBar1.SimpleText := 'Update Criteria=adCriteriaAllCols';
    end;
    end;
    end;

    end.
    </pre>
    Über die Anweisung <b>Properties['Update Criteria'].Value := adCriteriaKey;</b> wird das Recordset-Objekt davon informiert, dass <b>nur</b> der <b>Primärschlüsselwert</b> des betroffenen Datensatzes in der WHERE-Klausel genutzt werden soll. Somit ist die UPDATE- bzw. DELETE-Aktion immer dann erfolgreich, wenn <br>
    a) die Tabelle einen Primärschlüssel hat, und <br>
    b) kein anderer Benutzer den Primärschlüsselwert entsorgt hat.

    Schaltet man auf den anderen Radiobutton um, so bekommt man die Fehlermeldung "... Datensatz geändert..." zu Gesicht, wenn in der Zwischenzeit ein anderer Benutzer den Datensatz geändert hat.

    Wenn die Fehlermeldung auch im Einbenutzer-Betrieb kommt, werden Datentypen genutzt, die in Delphi zu Rundungsfehlern führen. Auch auch in diesem Fall beseitigt adCriteriaKey das Problem (solange der Primärschlüssel eindeutig ist, was bei einem INTEGER immer der Fall ist)

    Comment


    • #3
      Vielen Dank für die Antwort,

      allerdings habe ich hierzu noch eine Frage :

      Wie verhält sich ADO bei der Einstellung 'Update Criteria=adCriteriaKey' wenn der Primärschlüssel ein Autozähler ist, der beim INSERT noch nicht bekannt ist ?

      Vielen Dank im Voraus

      Marku

      Comment


      • #4
        Hallo,

        &gt;..ein Autozähler ist, der beim INSERT noch nicht bekannt ist ?

        wie der Name <i><b>Update</b> Criteria</i> schon andeutet, ist dieser Wert nur für UPDATE- und DELETE-Anweisungen relevant, bei denen es eine WHERE-Einschränkung gibt. Da bei einem INSERT kein WHERE-Part zulässig ist, hat diese Einstellung beim Einfügen von neuen Datensätzen keine Auswirkung.

        Beispiele: <br>
        a) UPDATE Tabelle SET Feld1=NeuerWert WHERE Primärschlüsselwert=1 <br>
        b) DELETE FROM Tabelle WHERE Primärschlüsselwert=1<br>
        c) INSERT INTO Tabelle (Feld1) VALUES ('NeuerWert'

        Comment


        • #5
          Hallo,

          merci für die Antwort ... Ich glaube, ich muss meine Frage anders formulieren :

          Wenn ich einen neuen Datensatz mit <B>Dataset.Append</B> ... <B>Dataset.Post</B> anlege, dann sollte das Dataset nach dem Post den Datensatz neu laden, bzw. auf diesem stehen. Wie soll also das Dataset den Datensatz neu laden können, wenn zu diesem Zeitpunkt der Autozähler-Wert noch nicht bekannt ist, um diesen eindeutig zu identifizieren ?

          Wie geht das Dataset dann vor, um den neu angelegten Datensatz zu lokalisieren, denn anscheinend versucht das Dataset ja irgendwas neu zu laden ?
          Die neuen Daten stehen jedenfalls in der Tabelle ?

          Ich kann mir nur vorstellen, dass das Dataset den Datensatz lädt, auf dem es sich vor dem <B>Dataset.Append</B> gestanden hat. Sollte dies der Fall sein, so müsste ich den Datensatz manuell hersuchen; was prinzipiell auch kein Problem wäre, sofern ich die Auto-Refresh Funktionalität abschalten kann

          Comment


          • #6
            Hallo,

            &gt;..Wie soll also das Dataset den Datensatz neu laden können...

            die VCL (TADODataSet) ist nur die Umverpackung für das Recordset-Objekt von ADO. Und auch das Recordset-Objekt von ADO ist nur die Umverpackung des eingebundenen OLE DB-Providers. Und im Fall des OLE DB-Providers für den MS SQL Server hat Microsoft bereits die Fähigkeit, IDENTITY-Werte automatisch zum Client zurückzuschicken, fest in den OLE DB-Provider und das Recordset-Objekt eingebaut. Somit holt sich ADO die benötigten Daten automatisch über @@IDENTITY vom SQL Server ab. Das TADODataSet bekommt von alle dem nichts mit, so dass dort der vom Server vergebene Primärschlüsselwert nach dem Post wie von Geisterhand auftaucht

            Comment

            Working...
            X