Entwickler-Ecke

Delphi Tutorials - Mit tTable & tQuery Arbeiten


Klabautermann - Di 02.07.02 01:06
Titel: Mit tTable & tQuery Arbeiten
Arbeiten mit Tabellen
Häufig ist es wünschenswert aus dem Quelltext direkt auf die Tabelle zuzugreifen. Da es nicht sehr sinnvoll ist den Text in extra hierfür angelegten DBEdit Feldern zu ändern, gibt es eine Reihe von Möglichkeiten um das Tabellenobjekt selbst zu manipulieren. Die wichtigsten werden hier kurz vorgestellt.
Navigieren
Jede Operation kann nur auf den aktuellen Datensatz angewandt werden. Damit dies nicht zum Problem wird, gibt es verschiedene Befehle zum Versetzen des Positionszeigers. Die fünf wichtigsten sind:

Delphi-Quelltext
1:
2:
3:
4:
5:
  Table1.First; // Zum ersten Datensatz
  Table1.Last; // Zum letzten Datensatz
  Table1.Prior; // Zum vorherigen Datensatz
  Table1.Next; // Zum nächsten Datensatz
  Table1.MoveBy(Distance); // Positionszeiger um Distance-Datensätze verschieben

Filtern
Neben diesen grundlegenden Navigationsmethoden gibt es noch erweiterte Suchfunktionen.
Die universellste Möglichkeit ist die Filter-Eigenschaft. Über diese lassen sich eine oder mehrere Bedingungen definieren die zutreffen müssen, damit ein Datensatz angezeigt wird. Sobald die Eigenschaft Filtered auf TRUE gesetzt wurde, beziehen sich alle Navigationsmethoden auf die gefilterte Datenmenge; es ist also nicht mehr möglich Datensätze zu erreichen die nicht den Filterregeln entsprechen. Der Wert von Filter kann nur geändert werden, wenn Filtered FALSE ist. Filter auf Indexfelder sind wesentlich schneller als Filter auf nicht-indexierte Felder. Eine typische Filterbedingung könnte folgendermaßen in einem Adressprogramm implementiert werden:

Delphi-Quelltext
1:
2:
3:
  tblAdressen.Filtered := FALSE;
  tblAdressen.Filter := 'Nachname=''Mustermann'' AND Vorname=''Max''';
  tblAdressen.Filtered := TRUE;

Auf Felder zugreifen
Es stehen mehrere Möglichkeiten zur Verfügung die Felder zu lesen oder zu schreiben.
Eine Möglichkeit ist der Zugriff über die Eigenschaft Fields. Diese ermöglicht es direkt über die Feldnummer zuzugreifen. Mit folgendem Aufruf wurde der Komponente Edit1 der Nachname aus der bereits bekannten Adressdatenbank zugewiesen (Nachname ist die dritte Spalte in der Tabelle):

Delphi-Quelltext
1:
Edit1.Text := tblAdressen.Fields.Fields[2].AsString;                    

Wie zu erkennen ist, sollte zusätzlich über die As*-Anweisung der vorliegende Datentyp angegeben werden.
Der Zugriff über die Datenfeldnummer ist nur dann sinnvoll, wenn man die Tabellenstruktur nicht kennt oder mit Schleifen arbeitet. Glücklicherweise kommt das recht selten vor. Eleganter und weniger fehleranfällig ist die Möglichkeit über den Feldnamen zuzugreifen. Hierzu kann FieldByName verwendet werden, welches ganz ähnlich funktioniert:

Delphi-Quelltext
1:
Edit1.Text := tblAdressen.FieldByName('Nachname').AsString;                    

Datensätze bearbeiten
Natürlich kann nicht nur aus den Feldern gelesen werden, es ist auch möglich in diese zu schreiben. Für gewöhnlich befindet sich ein Datensatz in einem schreibgeschützen Modus. Dieser kann allerdings mit der Methode Edit aufgehoben werden. Nachdem die Änderungen durchgeführt wurden, müssen sie mit dem Befehl Post gespeichert werden. Wenn Post noch nicht aufgerufen wurde, ist es möglich mit Cancel alle Änderungen, welche seit dem aufruf von Edit durchgeführt wurden, rückgängig zu machen und wieder in den schreibgeschützten Modus zurückzukehren. Die Verwendung von Post oder Cancel ist bei allen manipulativen Operationen nötig. Wenn das vorhergegangene Beispiel also umgedreht werden soll und der Wert aus Edit1 in der Datenbank landen soll, muss das so aussehen:

Delphi-Quelltext
1:
2:
3:
tblAdressen.Edit;
tblAdressen.FieldByName('Nachname').AsString := Edit1.Text;
tblAdressen.Post;

Neue Datensätze anlegen
Um einen neuen Datensatz an die Tabelle anzuhängen kann alternativ zu Edit der Befehl Append verwendet werden. Wenn der Datensatz nicht angehängt, sondern an der aktuellen Position eingefügt werden soll, ist Insert zu verwenden.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
tblAdressen.Insert; // Neuen Datensatz an der Aktuellen Position einfügen
tblAdressen.FieldByName('Nachname').AsString := Edit1.Text;
tblAdressen.Post;
tblAdressen.Append; // Neuen Datensatz an die Tabelle anhängen
tblAdressen.FieldByName('Nachname').AsString := Edit1.Text;
tblAdressen.Post;

Datensätze löschen
Den aktuellen Datensatz zu löschen ist denkbar einfach. Hierzu muss lediglich der Befehl Delete aufgerufen werden.

Delphi-Quelltext
1:
TblAdressen.Delete;                    

Neue Tabellen anlegen
Generell ist es natürlich möglich, Tabellen mit speziellen Programmen zu erstellen. Es ist aber nicht zu empfehlen, Programme mit vorher angelegen Tabellen auszuliefern, denn das bedeutet mehr fehlerquellen. So könnte es z.B. passieren, dass man beim erstellen des Setup Programmes eine Falsche Tabelle einbindet. Deshalb sollte es einem Programm möglich sein, seine Tabellen selber anzulegen. Wie das geht, wird hier am Beispiel unserer Adresstabelle demonstriert:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
    tblAdressen.TableType := ttParadox;
    tblAdressen.FieldDefs.Clear;
    tblAdressen.FieldDefs.Add('ID', ftAutoinc, 0, True);
    tblAdressen.FieldDefs.Add('Vorname', ftString, 30, FALSE);
    tblAdressen.FieldDefs.Add('Nachname', ftString, 30, FALSE);
    tblAdressen.FieldDefs.Add('Strasse', ftString, 50, FALSE);
    tblAdressen.FieldDefs.Add('PLZ', ftInteger, 0, FALSE);
    tblAdressen.FieldDefs.Add('Ort', ftString, 20, FALSE);
    tblAdressen.IndexDefs.Clear;
    tblAdressen.IndexDefs.Add('iID''ID', [ixPrimary,ixUnique]);
    tblAdressen.CreateTable;

Wie wir sehen werden unter FieldDefs die Spalten angelegt und unter IndexDefs die Indexdatei bestimmt. Das Ganze wird dann mit CreateTable erzeugt. Der Add Befehl für Felddefinitionen erwartet folgende Parameter:

Delphi-Quelltext
1:
(Bezeichnung, Datentyp, Größe, MussWertEnthalten)                    

Bei den IndexDefs sieht das so aus:

Delphi-Quelltext
1:
(Bezeichnung, ListeDerFelder, Indexbedingungen)                    

Arbeiten mit Querys
Richtig flexibel wird das Arbeiten mit Tabellen erst durch gezielte Datenbankanfragen. Die meisten Datenbanken erlauben es Anfragen in der Structured Query Language zu stellen (SQL). Hierzu wird die tQuery-Komponente (oder ein Äquivalent) verwendet. Da hier kein Raum für einen SQL-Kurs ist, gehe ich davon aus, dass diese Sprache zumindest in Ansätzen beherrscht wird, und gehe nur auf den DELPHI-spezifischen Umgang mit diesen ein.
SQL-Anweisungen zuweisen
Das SQL-Objekt besitzt ein Unterobjekt mit dem Namen SQL vom Typ tStrings. Sowohl zur Designzeit als auch zur Laufzeit können hier Querys eingegeben werden. Auch hierzu ein Beispiel:

Delphi-Quelltext
1:
2:
3:
4:
Query1.SQL.Clear;
Query1.SQL.Add('SELECT *');
Query1.SQL.Add('FROM Adressen');
Query1.SQL.Add('WHERE Nachname=''Mustermann''');

Arbeiten mit Parametern
Natürlich ist es möglich die SQL-Strings dynamisch zur Laufzeit zu erzeugen. Sollte es jedoch nur darum gehen Werte auszutauschen bietet DELPHI die Möglichkeit Parameter zu verwenden. Diese werden im Query mit einem Doppelpunkt ( : ) angegeben und können Ihren Wert später mit ParamByName('Parametername').As* erhalten. Unser Beispiel mit Parameter:

Delphi-Quelltext
1:
2:
3:
4:
5:
Query1.SQL.Clear;
Query1.SQL.Add('SELECT *');
Query1.SQL.Add('FROM Adressen');
Query1.SQL.Add('WHERE Nachname=:NName');
Query1.ParamByName('NName').AsString := 'Mustermann';

Querys ausführen
Beim Ausführen von Querys muss beachtet werden, ob es sich um lesende oder schreibende Querys handelt. Lesende Querys werden mit einem Aufruf von Open ausgeführt. Mit dem Query-Objekt kann dann ähnlich gearbeitet werden wie mit einer Tabelle. Bis es mit Close wieder geschlossen wird. Die SQL-Anweisung kann nicht verändert werden, solange das Query offen ist.
Schreibene Querys (z.B. CREATE TABLE, UPDATE usw.) werden hingegen mit ExecSQL ausgeführt, da es keinen Sinn macht einen solchen Befehl öffnen zu wollen.

Ich hoffe mit dieser kleinen Einführung in das Weite Feld der Datenbankprogrammierung kann der eine oder andere etwas anfangen. Jeden der sich ernsthaft damit beschäftigen will sei SQL ans Hetz gelegt. Es vereinfacht die Arbeit mit Datenbanken enorm und bietet dabei noch mehr Möglichkeiten als das reine verwenden von tTable.
Auch wenn es im ersten moment unheimlich kompliziert aussieht sollte man sich nicht abschrecken lassen - tatsächlich ist es nicht schwerer als z.B. HTML.

Viel Erflog
Klabautermann


wwerner - Fr 12.07.02 15:00

:lol: Hey, gut geschrieben

Wolfgang


AlexW93 - So 02.10.11 19:51

Obwohl der Thread schon ziemlich alt ist, möchte ich mich trotzdem bedanken. Hilft mir wirklich weiter! :)

Alex


Klabautermann - Di 04.10.11 17:41

user profile iconAlexW93 hat folgendes geschrieben Zum zitierten Posting springen:
Obwohl der Thread schon ziemlich alt ist, möchte ich mich trotzdem bedanken. Hilft mir wirklich weiter! :)

Das freut mich zu lesen, eigentlich müsste ich den mal modernisieren, es ist mit DBExpress ja eine etwas komplizierterer Variante der tDataset Systematik in der Delphi Welt aufgetaucht (Unidirektionale Datenmengen, Dataset-Provider usw.). Mal sehen ob ich mich motivieren kann.

Gruß
Klabautermann