SQLClientDataSet->LoadFromFile() - Filedaten in die DB, wie?
-
Hallo,
ich habe einen Datensatz aus einer DB mittels SQLClientDataSet->SaveToFile() in ein File gespeichert.
SQLClientDataSet->SaveToFile(File, dfBinary);Wenn ich den Datensatz jetzt an andeter Stelle (inszwischen gab es einen Disconnect und evtl. wurde auch das Programm beendet) wieder mit SQLClientDataSet->LoadFromFile() lade, habe ich zwar die Daten in dem SQLClientDataSet, aber ich kriege sie nicht in die Datenbank. Ich gehe so vor:
[/cpp]// Daten laden SQLClientDataSet->LoadFromFile(File); SQLClientDataSet->Active = true; // Änderungen werden an die DB übertragen SQLClientDataSet->ApplyUpdates(-1);Wenn ich mir jetzt mit einem anderen Programm den Datenbank inhalt anschaue, ist dort aber noch der alte Inhalt (ich habe ihn zwischen den Speichern und Laden ausgetauscht).
Debugge ich das SQLClientDataSet, oder sehe mir mir "FileByName("xyz")" die Inhalte an, sehe ich, dass das SQlLCientDataSet die INhalte korrekt aus dem File geladen hat. Nur die Übertragung zur DB geht nicht, oder findet nicht statt.Weiß jemand was ich flasch mache?
Danke!
-
Clip,
Clip schrieb:
Weiß jemand was ich flasch mache?
ich habe zwar noch nie mit TClientDataSet gearbeitet, versuche es aber trotzdem mal.
Vermutung 1: Beim Laden aus einem "flat file" ersetzt Du den kompletten Inhalt des DataSets mit unveränderten Daten. Das könntest Du prüfen, indem Du die Datensätze durchläufst und die "Modified"-Property für die Datensätze prüfst. Wenn nichts modifiziert ist, kannst Du auch nichts Updaten, würde ich sagen.
Vermutung 2: Beim Laden der Datenmenge aus einer Datei änderst Du automatisch auch die Datenquelle (siehe Property "FileName").
Falls das alles stimmt, könntest Du zwei ClientDataSet's verwenden: eins für die "echte" Datenbank und eins für den Datei-Zugriff. Nach dem Laden aus der Datei übernimmst Du die Daten aus dem File-DataSet in das Datenbank-DataSet und führst danach das Update für die Datenbank aus.
Falls das alles Quatsch war: bitte nicht Schlagen und einfach ignorieren
-
Danke, ich werde es gleich einmal ausprobieren!
Mit was für Datenklassen arbeitest Du denn?
Ich bin ja nicht mit dem SQLClientDataSet verheiratet. Ich kenne nur nichts besseres (OK, SQLQuery für simple Abfragen). Allerdings habe ich immer häufiger das Gefühl das die ganze Welt inzwischen etwas anderes benutzt, ich aber nichts davon weiß. Wenn ich im Netz eine Suche nach diesen Themen starte, finde ich immer eine Menge Multi Tier bezogene Postings, die im Zeitraum 1999 - 2001 enstanden sind.
-
Clip,
Clip schrieb:
Allerdings habe ich immer häufiger das Gefühl das die ganze Welt inzwischen etwas anderes benutzt, ich aber nichts davon weiß.
welche DB-Komponenten Du benutzt, hängt von Deiner Anwendung ab. Man kann unterscheiden zwischen:
-
Klassische (verbundene) Client-Server-Anwendung
Hier ist/war die BDE die erste Wahl bzw. die "alten" (2.x) ADO-Komponenten.
Charakteristisch ist, daß der Client über einen Server-seitigen Cursor eine dauerhafte Verbindung zum Server aufrecht erhält, was die Programmierung des Clients sehr erleichtert. Durch ein TDataSet::Edit() kann so z.B. eine Sperrung des betreffenden Datensatzes vorgenommen werden, was das Problem konkurrierender Zugriffe auf einfache (und drakonische) Art löst.
Als Nachteil gelten hier die Performance-Einbußen auf der Seite des Servers. -
Verbindungslose Anwendung
Hier ist das Grundprinzip das folgende: Lege eine Kopie der Daten im Hauptspeicher des Clients an (TClientDataSet), arbeite mit den Daten (ändern, löschen, hinzufügen) und schreibe Sie anschließend wieder zurück auf den Server. Diese Art der Datenverarbeitung zielt also auf Internet-Browser-ähnliche Anwendung ab (lade Daten, fülle die Seite, schreibe Daten zurück).
Das neue ADO.NET arbeitet z.B. komplett nach diesem Prinzip, was vielen den Schweiß auf die Stirn treibt (mich eingeschlossen).
So ungefähr würde ich es beschreiben, gebe aber keine Garantie auf Vollständigkeit.
-
-
Das Problem sit in der Tat das Modified Property. Es steht immer auf false.
Ich wollte dann TSQLClientData überchreiben in TMySQLClientDataSet.Sinn des ganzen ist Modified public zu machen, um dann einfach zur Laufzeit Modified = true zu setzten.
.h
class TMySQLClientDataSet : public TSQLClientDataSet { public: __fastcall virtual TMySQLClientDataSet(Classes::TComponent* AOwner); bool Modified; };.cpp
__fastcall TMySQLClientDataSet::TMySQLClientDataSet(Classes::TComponent* AOwner) { }Wenn ich jetzt ein Objekt erzeuge kommt beim Kompilieren folgende Fehlermeldung:
[C++ Fehler] TCopyAction.cpp(24): E2251 Standardkonstruktor zum Initialisieren der Basisklasse 'TSQLClientDataSet' nicht gefunden
Vollständiger Parser-Kontext
TCopyAction.cpp(24): Analyse von: _fastcall TMySQLClientDataSet::TMySQLClientDataSet(TComponent
Was mache ich falsch?
-
Clip,
Clip schrieb:
Ich wollte dann TSQLClientData überchreiben in TMySQLClientDataSet.
Sinn des ganzen ist Modified public zu machen, um dann einfach zur Laufzeit Modified = true zu setzten.also prinzipiell würde ich davon absehen. Das sollte der absolute letzte Ausweg sein. Du könntest statt dessen versuchen, für alle betreffenden Datensätze einen beliebigen Feldinhalt mit sich selbst zu überschreiben. TDataSet bekommt es normalerweise nicht mit, daß nicht wirklich eine Änderung der Daten vorgenommen wurde und kennzeichnet die Datensätze trotzdem als modified. (Allerdings glaube ich, daß es da noch eine intelligentere Lösung geben sollte.)
Was die Ableitung betrifft:__fastcall TMySQLClientDataSet::TMySQLClientDataSet(Classes::TComponent* AOwner) : TSQLClientDataSet(AOwner) { }Einen Standard-Konstruktor für TSQLClientDataSet gibt es nicht, daher mußt Du dem Compiler sagen, welcher Konstruktor der Basisklasse aufgerufen werden soll.