mit IBDataSet auf Index in fdb zugreifen
-
Hallo,
danke für die schnelle Antwort. Ich benutze schon die order by klausel in der Select-SQL bsp: "SELECT * FROM T_REGISTER ORDER BY \"Name\"". Leider funktioniert das nur sobald ich die Abfrage mach (IBDataset Aktiv) wenn ich jetzt z.B. einen neuen Datensatz add'e dann steht der am ende vom dbGrid. Es muß doch ne möglichkeit geben das es automatisch geupdatet wird. Ich kann doch nicht jedesmal wenn ein datensatz geändert oder eingefügt wird IBDataset->Close und IBDataset->Aktiv aufrufen nur um den datensatz an der richtigen stelle zu haben das ist doch net gut für die performance!
Danke.
-
Hallo
Das DBGrid kann sich nicht automatisch updaten, denn es weiß ja gar nicht was für eine ORDER bei der Abfrage verwendet wurde. Du must in der Tat die alte Abfrage schließen und die Abfrage mit der gleichen ORDER-Anweisung neu ausführen.
bis bald
akari
-
Hallo,
was steht im RefreshSQL ? Ebenfalls order by ?
Du kannst ausserdem mit der Eigenschaft - ForcedRefresh - eine Aktualisierung
erzwingen. Ansonsten mit Dataset->Refresh manuell.
Was die Perfomance angeht würde ich das von der Datenbankseite erstmal als nicht so gravierend ansehen. Du musst den Datenbankserver abfragen, da dieser für die Indexierung zuständig ist und diese auch durchführen sollte. Im anderen Fall mußt du auf der Clientseite selbst sortieren, was auch Resourcen kostet.
-
Also,
habe mal in RefreshSQL mit oder by und ohne ausprobiert und nix das ForcedRefresh=true bringt au genauso wenig wie wenn ich Dataset->Refresh() nach jeden Dataset->Post() aufrufe!
Was mach ich falsch??
Das kann doch net so schwer sein!PS: Bei der order by klausel gebe ich die tabelle an brauche ich da noch den aufsteigenden bzw. absteigenden index für die tabelle wenn ich den index eh net direkt ansprechen kann???
-
Hast du die Transaktion abgeschlossen ?
(Commit bzw. CommitRetaining )zum P.S.
Die komplette Indexverwaltung macht der Server. Wenn du eine Abfrage and den Server stellst schaut dieser selber nach, ob und was er sortieren muß oder ob ein Index vorhanden ist.
Der Client braucht nichts über Indexe auf der Datenbank zu wissen. (Nur sollte der DB-Admin klugerweise die wichtigsten angelegt haben
). Durch das SQL Statement sagt der Client was er haben will und der Server versucht das schnellstmöglich zu liefern. Ist kein Index da, wird die Ergebnissmenge eben vom Server neu sortiert.
-
Hallo,
erstmal vielen dank für eurer mühe, aber es will immer noch net so recht also schreibe ich jetzt mal wie ich das mache:
Komponenten:
- IBDatabase verbunden mit IBTransaction
- IBDataSet verbunden mit IBDatabase und IBTransaction
- DataSource verbunden mit IBDataSet
- DBGrid verbunden mit DataSourceIBDataSet DeleteSQL: delete from T_TEST where "Test ID" = :"OLD_Test ID"
IBDataSet InsertSQL: insert into T_Test("Name", "Test ID")values( :"Name", :"Test ID")
IBDataSet ModifySQL: update T_TEST set "Name" = :"Name","Test ID" = :"Test ID" where "Test ID" = :"OLD_Test ID"
IBDataSet RefreshSQL: SELECT * FROM T_TEST where "Test ID" = :"Test ID" ORDER BY "Name"
IBDataSet SelectSQL: SELECT * FROM T_TEST ORDER BY "Name"Bsp. code:
IBDataSet->Append(); // bei neuen eintrag
IBDataSet->Edit();
IBDataSet->FieldByName("Test ID")->AsString=char(ID); // bei neuen Eintrag
IBDataSet->FieldByName("Name")->AsString=E_Caption->Text;
IBDataSet->Post();
IBDataSet->Refresh();
IBTransaction->CommitRetaining();Das sind die wichtigsten Einstellungen wie gesagt adden und ändern geht aber das DBGrid fügt es hinten an (beim adden) oder lässt den geänderten Eintrag unsortiert an der ursprünglichen stelle stehen!
Danke.

-
Ich kommentiere das einfach mal:
IBDataSet->Append(); // Datensatz anhängen und in Eingabemodus versetzen IBDataSet->Edit(); // Datensatz erneut in Eingabemodus versetzen? IBDataSet->FieldByName("Test ID")->AsString=char(ID); IBDataSet->FieldByName("Name")->AsString=E_Caption->Text; IBDataSet->Post(); // Änderungen an aktuellem Datensatz abschließen IBDataSet->Refresh(); IBTransaction->CommitRetaining(); // Transaktion abschließen, erst jetzt wird der ->Post() tatsächlich ausgeführtWieso eigentlich CommitRetaining und nicht Commit?
-
Hallo,
ich hab noch mal nachgeschaut. Soweit ich das jetzt sehe muß man im AfterPost Event des Datasets die Daten neu vom Server laden, damit im Grid die gewünschte Reihenfolge erscheint.
z.B. mit
void __fastcall TForm1::IBDataSet1AfterPost(TDataSet *DataSet) { IBDataSet1->Active = false; IBDataSet1->Active = true; }Das ->Edit() kann man sich sparen (Append setzt den neuenDatensatz in den Bearbeitungsmodus)
Den ->Refresh() Aufruf kann man sich auch sparen, da er normal nur den aktuellen Datensatz holt (siehe RefreshSQL).Die Methode Post schreibt die Änderungen in die Datenbank. Solange die Transaktion noch nicht abgeschlossen ist, ist die Änderung für andere Transaktionen auch noch nicht sichtbar. Erst mit Commit oder CommitRetaining wird die Transaktion abgeschlossen und die Änderungen werden tatsächlich in der Datenbank für alle sichtbar. Der Unterschied zwischen Commit und Commit Retaining ist, dass beim 2.ten der Transaktionskontext erhalten bleibt. D.h. z.B das die aktuelle Position in der Datenmenge erhalten bleibt und nicht auf den ersten Datensatz wechselt.
Frage: Gibt es einen Primärschlüssel?
Wo wird der erzeugt ?
-
Hallo,
also Primärschlüssel ist die ID (vom type char da ich net mehr als 255 Datensätze erwarte und dafür 1 Byte reicht) und wird beim erzeugen der Tabelle angelegt.
Wenn ich das Refresh() weglasse kann ich mir au das RefreshSQL-SQL-Statement sparen! Richtig?
Das is doch alles blöd wenn ich nen Datensatz ändere und dann CommitRetaining() nutze (damit es aktualisiert wird ohne die Transaktion zu beenden und damit der Datensatzzeiger auf der aktuellen Position bleibt) und dann trotzdem:
void __fastcall TForm1::IBDataSet1AfterPost(TDataSet *DataSet) { IBDataSet1->Active = false; IBDataSet1->Active = true; }aufrufen muß um den Datensatz im DBGrid richtig einsortieren zu lassen wobei mein Datensatzzeiger wider auf die erste Position fällt!
Ergo: Für mich ist Commit=CommitRetaining da ich nach beiden den Datensatzzeiger wieder Händisch auf die aktuelle Position setzen muß!Habe jetzt schon 2 Fachbücher durchsucht aber keine tolle andere Lösung gefunden um mein DBGrid auf den aktuellen zu halten! Hat vielleicht net jemand nen anderen Vorschlag????

Es muß da doch was geben da es bei IBTable au die tolle Funktion IndexName() gibt und IBTable doch IBDataSet untergeordnet is!
Die Funktion IndexName gibt es laut Hilfe in der Klasse TCustomClientDataSet die ja von IBDataSet abgeleitet sein müßte oder???
Also am beste wär es für mich wenn ich irgendwie das IndexName von TCustomClientDataSet benutzen könnte aber ka ob und wie ich das auf mein IBDataSet beziehen kann!!!

Danke
-
Commit vs. CommitRetaining geht hier weiter:
http://c-plusplus.net/forum/viewtopic-var-t-is-179400.html