Announcement

Collapse
No announcement yet.

ADO und dBase

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

  • ADO und dBase

    Fehler beim Schreibzugriff auf dBase-IV-Dateien mit logischen Datenfeldern unter ADO

    Bei der Umstellung einer Anwendung von BDE auf ADO treten Probleme mit sequentiellen Schreibzugriffen auf Ergebnismengen aus dBase-Tabellen auf, wenn diese Tabellen logische Datenfelder enthalten und mindestens ein Satz keinen Nullwert im logischen Feld enthielt.

    Zum Nachvollzug des o.a. Sachverhalts habe ich mit der Datenbankoberfläche von Delphi die dBase-IV-Tabelle "TEST1.DBF" mit den Spalten "FELD1" (30 Zeichen) und FELD2 (Logisch) in dieser Spaltenreihenfolge erstellt. In diese Tabelle schreibe ich einen String - z.B. "blabla" - in alle Felder mit folgendem Code:

    with ADODataSet1 do begin
    CommandText := 'SELECT * FROM test1';
    Close;
    Open;
    while not EOF do begin
    Edit;
    Fields[0].AsString := '000';
    Next;
    end;
    Close;
    end; // ADODataSet1

    Solange FELD2 in allen Feldern leer ist - d.h. Null-Werte enthält - ist alles in Ordnung. Die Daten werden ohne Fehlermeldung in alle Sätze geschrieben. Enthält mindenstans ein Satz in FELD2 einen Wert - True oder False - werden Fehlermeldungen ausgegeben - z.B.: "Ungenügende oder inkorrekte Schlüsselspalteninformation: es sind zu viele Zeilen von der Aktualisierung betroffen" - und die gewünschten Daten werden oft nur in einem Teil der Sätze oder garnicht nach FELD1 geschrieben.

    Der Fehler tritt auch auf,
    - wenn CommandText in "SELECT FELD1 FROM test1'" geändert wird oder
    - wenn die Tabelle zuvor nicht mit der Datenbankoberfläche sondern zur Laufzeit mit einer TADOCommand-Komponente und dem CommandText "CREATE TABLE TEST2.DBF (FELD1 CHAR(30),FELD2 LOGICAL)" erzeugt wurde.

    CanModify war in allen Fällen true.

    Der Fehler tritt nicht auf, wenn der Schreibzugriff mit einer TADOCommand-Komponente über den CommandText "UPDATE TEST1 SET FELD1=''3333''" erfolgt.

    Als Provider verwende ich den Microsoft OLE DB Provider for ODBC Drivers.

    Der Connenction-String lautet: "Provider=MSDASQL.1;Persist Security Info=False;User ID=ADMIN;Data Source=dBASE-Dateien;Connect Timeout=15;Locale Identifier=1031;Initial Catalog=D:\Projekte\Delphi5\Tests\ado"

    Hat jemand für das o.a. Verhalten eine Erklärung und/oder weiß jemand, wie man TADODataSet zu korrekten sequentiellen Schreibzugriffen in einer Datenmenge "überreden" kann oder ist das ein Bug in Delphi oder im Microsoft-ODBC-Treiber???????

  • #2
    Hallo,

    wenn ADO die Änderungen automatisch eintragen soll, benötigt ADO eine exakte Informationen darüber, welche Datensätze modifiziert werden sollen. Im o.g. Beispiel mit TADOCommand ist das beim UPDATE-Aufruf klar - da eine WHERE-Einschränkung fehlt, werden alle Datensätze modifiziert. Beim Zugriff über TADODataset ist das komplexer, da man selbst nur eine SELECT-Anweisung definiert, muss ADO intern die notwendigen UPDATE-Anweisungen generieren. Dies ist immer dann erfolgreich, wenn ein Primärschlüssel für die Datenbanktabelle zur Verfügung steht, da in diesem Fall ADO jeden einzelnen Datensatz exakt definieren kann. Die ADO-Fehlermeldung ".. ungenügende Schlüsselspalteninformation..." deutet exakt auf dieses Problem hin. Wenn ADO keinen Primärschlüssel hat, ist die Menge der zu aktualisierenden Datensätzen unter ungünstigen Umständgen nicht definierbar (siehe Fehlermeldung "...es sind zu viele Zeilen von der Aktualisierung betroffen...").

    Kann es sein, das die Kombination von Feld1+Feld2 zu Werten führt, die in der Tabelle nicht eindeutig sind (d.h. in der Tabellen sind mehrere Datensätze vorhanden, bei denen in beiden Feldern die gleichen Informationen stehen)? Kann es sein, das in Feld1 in verschiedenen Datensätzen gleiche Werte vorkommen können? Wenn ja, muss die Tabellenstruktur geändert werden, indem in einem zusätzlichen Feld (INTEGER) ein eindeutiger Primärschlüssel vergeben wird

    Comment


    • #3
      Sehr geehrter Herr Kosch,

      herzlichen Dank für Ihren freundlichen Kommentar. Auf Ihren Rat hin habe ich eine neue dBase-Tabelle TEST1 angelegt mit den Spalten "FELD1" (Numerisch), FELD2 (Logisch) und "FELD3" (30 Zeichen). Auf FELD1 habe ich einen eindeutigen, gewarteten Index definiert und für jeden Satz einen eindeutigen Wert eingetragen. Dann klappt sequentielles Schreiben mit Edit und Post über den CommandText "SELECT * FROM TEST1". Als ich dann aber versuchsweise eine größere Tabelle mit einem ebenfalls eindeutigen, gewarteten Index über einem CHAR-Feld heranzog, kamen wieder alle möglichen Fehlermeldungen. Außerdem war die Performance nicht akzeptabel. ADO und dBase-Tabelle, da paßt leider einiges noch nicht zusammen.

      Mit freundlichem Gruß

      Hans Grigul

      Comment

      Working...
      X