Sign in Join
Wiki copytemporary

SqlDBHowto/de: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11## Einleitung
22
33Diese Seite ist eine Übersetzung der Seite [[SqlDBHowto/nl]]. Der niederländische Text ist für die Übersetzung massgeblich, auch wenn ich mir die Freiheit genommen habe, einige Korrekturen (meiner Meinung nach kleinere Korrekturen) zu machen.\
4-\
4+
55Ich entschied mich für diese Art der Darstellung um einige Fragen zu beantworten und um zu zeigen, wie Sie ein Problem lösen können. Alle diese Fragen eine Frage nach der anderen zeigen auch, wie ein Tutorial erstellt wird.\
6-\
76
87## Verbinden mit einem Datenbankserver
98
109SqlDB verbindet sich nicht direkt mit einem Datenbankserver sondern verwendet einen Client, der mit dem verwendeten Datenbankserver kommuniziert. (Dieser Client wird meist vom Hersteller der Datenbank geliefert und wird lokal auf dem Computer installiert, der sich mit der Datenbank verbinden soll.) SqlDB sendet die Kommandos an die Client-Bibliothek, die sich mit der Datenbank verbindet und ihr die Kommandos übergibt. Unter Windows ist der Client üblicherweise eine .dll Datei, unter Linux eine .so und unter OS/X eine .dylib Datei.\
1110Wenn die Client-Bibliothek richtig installiert ist, kann man sich über eineTSQLConnection Komponente mit der Datenbank verbinden. Für den Zugriff auf die unterschiedlichen Datenbankserver gibt es eine Vielzahl von TSQLConnection Komponenten.\
12-\
11+
1312Zum Beispiel kann man sich:
1413
1514- mit der Komponente TIBConnection mit einer Firebird/Interbase Datenbank verbinden
1615- mit der Komponente TPQConnection mit einer PostgreSQL Datenbank verbinden
1716- mit der Komponente TMySQL56Connection mit einer MySQL Datenbank verbinden
1817- usw.
1918
2019Wenn auf ihrem Computer zum Beispiel die MySQL-Client-Bibliothek Version 4.1 installiert ist, sollte eine TMySQL41Connection verwendet werden, unabhängig von der Version des MySQL-Servers.\
21-\
20+
2221Obwohl die Details für die verschiedenen Datenbanken differieren, muss man im allgemeinen nur vier Eigenschaften setzen für die Verbindung zum Datenbankserver: den Namen der Datenbank, den Server-Namen oder die IP Adresse, den Benutzernamen und das Passwort. Wenn diese Eigenschaften gesetzt sind, können sie eine Verbindung mit der 'open' Methode herstellen. Wenn die Verbindung fehlschlägt, wird eine EDatabaseError Exception ausgelöst. Verwenden sie die 'connected' Eigenschaft um zu testen, ob die Verbindung zum Datenbank-Server hergestellt wurde. Mit der 'close' Methode beenden sie die Verbindung zum Server.
2322
2423``` pascal
2524 Program ConnectDB
2625
2726 var AConnection : TSQLConnection;
2827
2928 Procedure CreateConnection;
3029 begin
3130 AConnection := TIBConnection.Create(nil);
3231 AConnection.Hostname := 'localhost';
3332 AConnection.DatabaseName := '/opt/firebird/examples/employee.fdb';
3433 AConnection.UserName := 'sysdba';
3534 AConnection.Password := 'masterkey';
3635 end;
3736
3837 begin
3938 CreateConnection;
4039 AConnection.Open;
4140 if Aconnection.Connected then
4241 writeln('Erfolgreich verbunden!')
4342 else
4443 writeln('Es konnte keine Verbindung zur Datenbank erstellt werden. ' +
4544 'Wenn Sie in Ihrem Programm hier weitermachen, dann lösen Sie eine Exception aus.');
4645 AConnection.Close;
4746 AConnection.Free;
4847 end.
4948```
5049
51-\
5250Wird eine Exception ausgelöst, dann lesen Sie bitte die Fehlermeldung sorgfältig. Möglicherweise geht der Datenbankserver nicht oder der Benutzername oder das Kennwort ist falsch, oder der Datenbankname oder die IP-Adresse wurden falsch geschrieben. Sagt zum Beispiel, die Fehlermeldung, dass die Client-Bibliothek der Datenbank nicht gefunden wurde, dann überprüfen Sie bitte, ob die Client-Bibliothek der Datenbank korrekt installiert ist.\
5351
5452## Abfragen direkt ausführen / Eine Tabelle erstellen
5553
5654SQLdb - der Name sagt es bereits - funktioniert nur mit Datenbankservern, die Gebrauch von SQL machen. SQL steht für 'Structured Query Language'. SQL ist eine Sprache die entwickelt wurde, um das Arbeiten mit relationalen Datenbanken zu ermöglichen. Jedes Datenbanksystem benutzt einen eigenen Dialekt. Aber die überwiegende Anzahl von SQL Anweisungen ist für alle Datenbanksysteme gleich. Man unterscheidet zwischen Anweisungen, die Informationen zurückgeben, und Anweisungen, die keine Informationen zurückgeben. Wenn sie die Informationen nutzen wollen, die von einer SQL Anweisung zurückgegeben werden, dann müssen die TSQLQuery Komponente verwenden (siehe Daten aus einer Tabelle lesen). Wollen Sie dagegen keine Informationen von Ihrem Datenbankserver verarbeiten, dann müssen Sie die Methode 'ExecuteDirect' der Klasse TSQLConnection verwenden.\
57-\
55+
5856Die meisten Datenbank-Server können in einer Transaktion SQL Anweisungen auszuführen. Sie können auch mehrere SQL Anweisungen zu einer Transaktion zusammenfassen. Transaktionen werden mit einem 'StartTransaction' begonnen und mit einem 'commit' beendet. Um Transkationen durchführen zu können enthält sqldb die Komponente TSQLTransaction. Eine SQL-Anweisung, die von sqldb ausgeführt wird, muss immer innerhalb einer Transaktion ausgeführt werden. Auch dann, wenn das Datenbanksystem keine Transaktionen unterstützt.\
59-\
57+
6058Wenn Sie einen SQL-Befehl mit TSQLConnection.ExecuteDirect ausführen möchten, müssen Sie zunächst angeben, welche Transkation (TSQLTransaction) verwendet werden soll. Der Transaktion (TSQLTransaction) wiederum, müssen Sie angeben, welche Verbindung (TSQLConnection) verwendet werden soll.\
61-\
59+
6260Das folgende Beispiel erstellt eine Tabelle 'TBLNAMES' mit den Feldern 'NAME' und 'ID' und fügt zwei Datensätze ein. Die verwendeten SQL Anweisungen sind nicht erläutert. Für weitere Informationen über die SQL Anweisungen, ihre Verwendung und Schreibweise schauen sie bitte in der Dokumentation ihres Datenbanksystems nach. Die Prozedur 'CreateConnection' ist im Code-Beispiel im Abschnitt Verbinden mit einem Datenbankserver definiert.
6361
6462``` pascal
6563 program CreateTable;
6664
6765 var AConnection : TSQLConnection;
6866 ATransaction : TSQLTransaction;
6967
7068 procedure CreateTransaction;
7169 begin
7270 ATransaction := TSQLTransaction.Create(nil);
7371 ATransaction.Database := AConnection;
7472 end;
7573
7674 begin
7775 CreateConnection;
7876 CreateTransaction;
7977 AConnection.Transaction := ATransaction;
8078 AConnection.Open;
8179 ATransaction.StartTransaction;
8280 AConnection.ExecuteDirect('create table TBLNAMES (ID integer, NAME varchar(40));');
8381
8482 // Einige Datenbankserver benöigen ein commit, bevor sie eine neu erzeugte Tabelle nutzen können. (Firebird)
8583 // Mit .Commit schließen sie auch die Transaktion.
8684 ATransaction.Commit;
8785
8886 ATransaction.StartTransaction;
8987 AConnection.ExecuteDirect('insert into TBLNAMES (ID,NAME) values (1,'Name1');');
9088 AConnection.ExecuteDirect('insert into TBLNAMES (ID,NAME) values (2,'Name2');');
9189 ATransaction.Commit;
9290 AConnection.Close;
9391 AConnection.Free;
9492 ATransaction.Free;
9593 end.
9694```
9795
9896## Daten aus einer Tabelle lesen
9997
10098Verwenden sie die TSQLQuery Komponente, um Daten aus einer Tabelle zu lesen. Eine TSQLQuery Komponente muss mit einer TSQLConnection und einer TSQLTransaction Komponente verbunden werden, damit sie funktionieren kann.\
10199Die Themen TSQLConnection und TSQLTransaction wurden in den Abschnitten Verbinden mit einem Datenbankserver und Abfragen direkt ausführen / Eine Tabelle erstellen behandelt.\
102-\
100+
103101Wenn TSQLConnection, TSQLTransaction und TSQLQuery verbunden sind, dann werden weitere Einstellungen für TSQLQuery benötigt. TSQLQuery besitzt eine 'SQL' Eigenschaft, die ein TStrings Objekt enthält. Die 'SQL' Eigenschaft enthält eine SQL Anweisung, die ausgeführt werden muss. Wenn alle Daten aus einer Tabelle gelesen werden sollen, dann setzten sie die 'SQL' Eigenschaft auf 'SELECT * FROM tablename;'. Verwenden sie 'open', um die Tabelle auf dem Server auszulesen und die Daten im TSQLQuery dataset abzulegen. Auf die Daten kann über TSQLQuery zugegriffen werden, bis diese mittels 'close' geschlossen wird. TSQLQuery ist eine Unterklasse von TDataset. TDataset besitzt eine 'Fields' Kollektion, die alle Spalten der Tabelle enthält. Das TDataset behält auch den aktuellen Datensatz im Auge. Verwenden sie die Eigenschaften '.First', '.Next', '.Prior' und '.Last', um den aktuellen Datensatz zu ändern. 'Bof' gibt 'True' zurück, wenn der erste Datensatz erreicht ist und 'Eof' gibt 'True' zurück, wenn der letzte Datensatz erreicht ist. Um den Wert eines Feldes im aktuellen Datensatz zu lesen müssen sie zunächst das richtige 'TField' Objekt herausfinden und dann 'AsString', 'AsInteger', etc. verwenden.
104102
105103Hier ist ein Beispiel, das alle Werte aus der im Abschnitt Abfragen direkt ausführen / Eine Tabelle erstellen selbst erstellten Tabelle ausliest.
106104
107105``` pascal
108106 Program ShowData;
109107
110108 var
111109 AConnection : TSQLConnection;
112110 ATransaction : TSQLTransaction;
113111
114112 function GetQuery : TSQLQuery;
115113 var
116114 AQuery : TSQLQuery;
117115 begin
118116 AQuery := TSQLQuery.Create(nil);
119117 AQuery.Database := AConnection;
120118 AQuery.Transaction := ATransaction;
121119 Result := AQuery;
122120 end;
123121
124122 var
125123 Query : TSQLQuery;
126124
127125 begin
128126 CreateConnection;
129127 CreateTransaction;
130128 Query := GetQuery;
131129 Query.SQL.Text := 'select * from tblNames';
132130 AConnection.Open;
133131 Query.Open;
134132 while not Query.Eof do
135133 begin
136134 Writeln('ID: ', Query.FieldByName('Name').AsInteger, 'Name: ' +
137135 Query.FieldByName('Name').AsString);
138136 Query.Next;
139137 end;
140138 Query.Close;
141139 AConnection.Close;
142140 Query.Free;
143141 ATransaction.Free;
144142 AConnection.Free;
145143 end.
146144```
147145
148146(Dieser Code ist natürlich noch nicht komplett. So fehlen z.B. 'try...finally' Blöcke. Wie auch immer der obige Code zeigt den reinen Datenbankcode.) Beachten sie, dass 'TSQLTransaction.StartTransaction' nicht verwendet wird. Das ist nicht notwendig. Wenn TSQLQuery geöffnet wird, wird die SQL Anweisung ausgeführt und wenn keine Transaktion verfügbar ist, dann wird eine Transaktion automatisch gestartet. Der Programmierer muss die Transaktion nicht explizit starten. Das selbe gilt für die von TSQLConnection gehaltene Verbindung. Die Verbindung wird bei Bedarf geöffnet. Die Zeile 'Aconnection.Open' wird nicht wirklich benötigt. Wenn eine TSQLTransaction gelöscht wird, dann wird ein automatischer 'rollback' ausgeführt. Die Änderungen an den Daten im Rahmen der Transaktion gehen verloren.
149147
150148### Warum gibt TSQLQuery.RecordCount immer 10 zurück?
151149
152150Um die Datensätze in einer Datenbank zu zählen verwenden sie '.RecordCount'. Jedoch zeigt '.RecordCount' die Anzahl von Datensätzen, die bereits vom Server geladen sind. Sqldb liest (per Voreinstellung) nicht alle Datensätze ein, wenn TSQLQuery geöffnet wird, sondern nur die ersten 10. Erst wenn auf den elften Datensatz zugegriffen wird, werden die nächsten 10 Datensätze geladen. Durch die Verwendung von '.Last' werden alle Datensätze geladen.
153151
154152Wenn sie die tatsächliche Anzahl von Datensätzen auf dem Server wissen müssen, dann rufen sie erst '.Last' auf und dann '.RecordCount'. Es gibt aber auch eine Alternative. Die Anzahl von Datensätzen, die der Server zurückgibt, wird mit der Methode '.PacketRecords' festgelegt. Der Vorgabewert ist 10. Wenn sie den Wert auf -1 setzen, dann werden alle Datensätze auf einmal geladen.
155153
156154### Lazarus
157155
158156Um die Daten einer Tabelle anzuzeigen können Sie diese (statt mit einer While-Schleife und mit einer Writeln Ausgabe anzuzeigen) die Komponenten von Lazarus verwenden. Gehen sie dazu in der Lazarus IDE in das Register 'SQLdb'. Legen Sie eine TSQLConnection, eine TSQLTransaction und eine TSQLQuery Komponente auf ein Formular. Verbinden Sie die Komponenten über Ihre Eigenschaften (Wie in den obigen Abschnitten bereits erwähnt.). Danach benötigen Sie noch eine TDatasource Komponente aus dem Register 'Data Access'. Diese verbinden Sie über die Eigenschaft 'TDatasource.DataSet' mit der Komponente TSQLQuery. Anschliessend legen Sie ein TDBGrid aus dem Register 'Data Controls' auf das Formular und verbinden die Eigenschaft 'TDBGrid.Datasource' mit der Komponente TDatasource.\
159-\
157+
160158Um zu sehen, ob alles funktioniert, stellen Sie in der Lazarus IDE die "Verbunden"-Eigenschaft der TSQLConnection auf 'True'. Die IDE wird sofort versuchen, sich mit dem Datenbankserver zu verbinden. Wenn das funktioniert, können Sie die 'TSQLQuery.Active-Eigenschaft auf 'True' setzen. Ist alles in Ordnung, dann sehen Sie - in der IDE - alle Daten aus der Tabelle auf dem Bildschirm.\
161-\
162159
163160## Daten in einer Tabelle ändern
164161
165162Um die Daten in einem Datensatz zu bearbeiten, muss TDataset (von dem TSQLQuery abgeleitet ist) in den Bearbeitungsmodus versetzt werden. Dies kann durch Aufrufen der Methoden '.Edit', '.Insert' oder '.Append' geschehen. Verwenden sie die Methode '.Edit', um den aktuellen Datensatz zu ändern. Verwenden sie die Methode '.Insert', um einen neuen Datensatz an der aktuellen Position einzufügen. Verwenden sie die Methode '.Append', um einen neuen Datensatz am Ende der Tabelle einzufügen. Im Bearbeitungsmodus können sie die Werte der Felder mit der Methode '.Fields' ändern. Verwenden Sie die Methode '.Post', um die neuen Daten auf ihre Gültigkeit zu prüfen. Sind die Daten gültig, dann wird der Bearbeitungsmodus automatisch verlassen. Wenn Sie zu einem anderen Datensatz wechseln - zum Beispiel durch die Verwendung der Methode'.Next' - und der Datensatz befindet sich im Bearbeitungsmodus, dann wird als erstes die Methode '.Post' aufgerufen. Verwenden sie die Methode '.Cancel', um alle Änderungen seit dem letzten Aufruf der Methode '.Post' zu verwerfen und um den Bearbeitungsmodus zu verlassen.
166163
167164``` pascal
168165 Query.Edit;
169166 Query.FieldByName('NAME').AsString := 'Edited name';
170167 Query.Post;
171168```
172169
173170Die Klasse TSQLQuery leitet die Verwendung der gepufferten Updates von der Klasse TBufDataset ab. Gepuffertes Update bedeutet, dass Sie nachdem Sie die Methode '.Post' angewendet haben, die Änderungen im Client sofort sichtbar sind, und zwar **bevor** diese Daten an dem Datenbankserver gesendet wurden. Erst wenn Sie die Methode '.ApplyUpdates' aufrufen, werden die Änderungen an den Datenbankserver und damit an die Datenbank gesendet. Nur dann erlangt der Datenbankserver Kenntnis von allen Änderungen. Die Änderungen werden innerhalb einer Transaktion von TSQLTransaction an den Datenbankserver gesendet. Stellen sie sicher, dass die richtige Transaktion eingestellt ist, bevor Sie die Methode '.ApplyUpdates' aufrufen. Nach dem Ausführen des Updates muss ein Commit ausgeführt werden um die Änderungen dauerhaft in der Datenbank zu speichern.\
174-\
171+
175172Das folgende Beispiel zeigt, wie sie die Daten in einer Tabelle ändern und die geänderten Daten mit einer Transaktion an den Datenbankserver senden und mit einem Commit dauerhaft in der Datenbank speichern.\
176173
177174``` pascal
178175 Program EditData;
179176
180177 var AConnection : TSQLConnection;
181178 ATransaction : TSQLTransaction;
182179 Query : TSQLQuery;
183180
184181 begin
185182 CreateConnection;
186183 CreateTransaction;
187184 AConnection.Transaction := ATransaction;
188185 Query := GetQuery;
189186 Query.SQL.Text := 'select * from tblNames';
190187 Query.Open;
191188 Query.Edit;
192189 Query.FieldByName('NAME').AsString := 'Edited name';
193190 Query.Post;
194191 Query.UpdateMode := upWhereAll;
195192 Query.ApplyUpdates;
196193 AConnection.Transaction.Commit;
197194 Query.Free;
198195 ATransaction.Free;
199196 AConnection.Free;
200197 end.
201198```
202199
203-\
204-
205200## Wie Sqldb Änderungen an den Datenbankserver sendet
206201
207202In dem Code-Beispiel in Daten in einer Tabelle ändern finden sie die Zeile
208203
209204``` pascal
210205Query.UpdateMode := upWhereAll;
211206```
212207
213208ohne Erläuterung, was dieser Befehl macht. Der beste Weg es herauszufinden besteht darin, die Zeile wegzulassen. Wenn sie die Anweisung weglassen und sich ansonsten genau an den Beispielcode halten, dann erhalten sie die folgende Fehlermeldung:
214209
215210`No update query specified and failed to generate one. (No fields for inclusion in where statement found)`
216211
217212Um zu verstehen, was schief gegangen ist, müssen sie wissen, wie Änderungen an den Datenbankserver gesendet werden. Der einzige Weg, um Daten in einen SQL-Server zu bekommen, besteht im Ausführen von SQL-Anweisungen. SQL kennt drei Typen von Anweisungen für drei verschiedene Wege der Manipulierung eines Datensatzes. Um einen (neuen) Datensatz zu erstellen, zu ändern oder zu löschen werden die insert, update und delete Anweisungen entsprechend ausgeführt. Eine update Anweisung könnte wie folgt aussehen:
218213
219214``` sql
220215update TBLNAMES set NAME='Edited name' where ID=1;
221216```
222217
223218Um eine Änderung an den Datenbank-Server zu senden, muss sqldb eine Aktualisierungsabfrage erstellen. Um diese Aktualisierungsabfrage zu erstellen, sind drei Dinge erforderlich:\
224219; Der Name der Tabelle: Der Tabellenname wird durch das Parsen (Durchsuchen, Analysieren) der SELECT-Abfrage ermittelt.
225220
226221`UPDATE` oder `INSERT` Abschnitt
227222Dieser enthält die Felder, die geändert werden sollen.
228223
229224`WHERE` Abschnitt
230225Dieser enthält die Felder, die bestimmen, welche Datensätze geändert werden sollen.
231226
232227Jedes Feld (jedes *TField* in *Fields*) besitzt eine ProviderFlags Eigenschaft. Nur Felder mit **pfInUpdate** in *ProviderFlags* werden in dem update oder insert Abschnitt einer query verwendet. Vorgabemäßig ist *pfInUpdate* bei allen Feldern in deren *ProviderFlags* Eigenschaft gesetzt.
233228
234-Welche Felder in der `WHERE`-Klausel verwendet werden müssen hängt vom Abschnitt Update der SQL-Abfrage (Eigenschaft '.SQL.Text') und von der Eigenschaft '.ProviderFlags' (<i>pfInWhere, pfInUpdate, pfInKey, pfHidden</i>) ab. Felder, die mit dem ProviderFlag <i>pfInKey</i> als Schlüsselfelder gekennzeichnet sind müssen in der `WHERE`-Klausel verwendet werden.\
235-Ist ein Feld Teil eines Primärschlüssels der Datenbanktabelle, dann ist für die Eigenschaft '.ProviderFlags' das Flag <i>pfInKey</i> automatisch eingestellt und die Eigenschaft '.UsePrimaryKeyAsKey' gibt den Wert '<i>True</i>' zurück.\
236-\
237-Der Standardwert für die Eigenschaft '.UpdateMode' ihrer Abfrage ist der Wert <i>upWhereKeyOnly</i>. In diesem Update-Modus wird in der WHERE-Klausel über die Eigenschaft '.ProviderFlags' mit dem Wert <i>pfInKey</i> eine oder mehrere Spalte(n) als Schlüsselfeld(er) gekennzeichnet. Wenn Sie für keines der Felder das Flag <i>pfInKey</i> gesetzt haben, dann kommt es zu einer Fehlermeldung. Sie können das Problem auf folgende Weise lösen:\
229+Welche Felder in der `WHERE`-Klausel verwendet werden müssen hängt vom Abschnitt Update der SQL-Abfrage (Eigenschaft '.SQL.Text') und von der Eigenschaft '.ProviderFlags' (pfInWhere, pfInUpdate, pfInKey, pfHidden) ab. Felder, die mit dem ProviderFlag pfInKey als Schlüsselfelder gekennzeichnet sind müssen in der `WHERE`-Klausel verwendet werden.\
230+Ist ein Feld Teil eines Primärschlüssels der Datenbanktabelle, dann ist für die Eigenschaft '.ProviderFlags' das Flag pfInKey automatisch eingestellt und die Eigenschaft '.UsePrimaryKeyAsKey' gibt den Wert 'True' zurück.\
231+
232+Der Standardwert für die Eigenschaft '.UpdateMode' ihrer Abfrage ist der Wert upWhereKeyOnly. In diesem Update-Modus wird in der WHERE-Klausel über die Eigenschaft '.ProviderFlags' mit dem Wert pfInKey eine oder mehrere Spalte(n) als Schlüsselfeld(er) gekennzeichnet. Wenn Sie für keines der Felder das Flag pfInKey gesetzt haben, dann kommt es zu einer Fehlermeldung. Sie können das Problem auf folgende Weise lösen:\
238233* Hinzufügen eines Primärschlüssels zur Tabelle und setzen des Wertes von TSQLQuery.UsePrimaryKeyAsKey auf 'True'. Beispiel für das Erstellen eines Primärschlüssels:
239234
240235``` pascal
241236 Query.UsePrimaryKeyAsKey := True;
242237```
243238
244-- Setzen des Flags <i>pfInKey</i> für ein oder mehrere Felder im Code. Beispiel für einen zusammengesetzten Schlüssel:
239+- Setzen des Flags pfInKey für ein oder mehrere Felder im Code. Beispiel für einen zusammengesetzten Schlüssel:
245240
246241``` pascal
247242 Query.FieldByName('Name').ProviderFlags := [pfInKey];
248243 Query.FieldByName('Vorname').ProviderFlags := [pfInKey];
249244```
250245
251246Die **UpdateMode** Eigenschaft kennt zwei weitere mögliche Werte:
252247
253248- 'upWhereAll': Der Wert 'upWhereAll' versorgt alle Felder mit dem Flag 'pfInWhere'. Damit werden alle Felder zur `WHERE`-Klausel hinzugefügt. Als Standard ist dieses Flag bei allen Feldern gesetzt.
254249- 'upWhereChanged': Der Wert 'upWhereChanged' sorgt dafür, dass nur die Felder in der `WHERE`-Klausel verwendet werden, die das Flag 'pfInWhere' haben und die im aktuellen Datensatz verwendet wurden.
255250
256-\
257-
258251## Wie führt man eine Abfrage unter der Verwendung von TSQLQuery aus?
259252
260253Neben den Anweisungen, die Daten zurückgeben (siehe Daten in einer Tabelle ändern), gibt es bei SQL Anweisungen, die keine Daten zurückgeben, zum Beispiel `INSERT`, `UPDATE` und `DELETE`. Diese Anweisungen können mittels *TSQLConnection.ExecuteDirect* ausgeführt werden, aber TSQLQuery kann ebenso verwendet werden. Wenn keine Daten zurückgegeben werden, dann verwenden sie *TSQLQuery.ExecSQL* anstatt *TSQLQuery.Open*. Die Methode *TSQLQuery.Open* wird verwendet um ein von einem SQL-Statement zurück gegebenes Dataset zu öffnen.\
261254Die folgende Prozedur erzeugt eine Tabelle mittels TSQLQuery und fügt zwei Datensätze ein.
262255
263256``` pascal
264257 procedure CreateTable;
265258
266259 var Query : TSQLQuery;
267260
268261 begin
269262 Query := GetQuery;
270263 Query.SQL.Text := 'create table TBLNAMES (ID integer, NAME varchar(40));';
271264 Query.ExecSQL;
272265
273266 Query.SQL.Text := 'insert into TBLNAMES (ID,NAME) values (1,'Name1');';
274267 Query.ExecSQL;
275268
276269 Query.SQL.Text := 'insert into TBLNAMES (ID,NAME) values (2,'Name2');';
277270 Query.ExecSQL;
278271
279272 Query.Close;
280273 Query.Free;
281274 end;
282275```
283-
284-\
285276
286277## Verwendung von Parametern in einer Abfrage
287278
288279Im Code-Beispiel von Wie führt man eine Abfrage unter der Verwendung von TSQLQuery aus? wird die selbe Abfrage zweimal verwendet, nur mit anderen einzusetzenden Werten. Eine bessere Möglichkeit dies zu erledigen ist die Verwendung von Parametern in der Abfrage.
289280
290281Die Syntax von Parametern in Abfragen ist je nach verwendeter Datenbank unterschiedlich. Aber diese Unterschiede können von TSQLQuery gehandhabt werden. Ersetzen sie die Werte in der Abfrage mit einem Doppelpunkt gefolgt von dem Namen des Parameters, den sie verwenden wollen.\
291282Zum Beispiel:
292283
293284``` pascal
294285 Query.SQL.Text := 'insert into TBLNAMES (ID,NAME) values (:ID,:NAME);';
295286```
296287
297288Diese Abfrage enthält zwei Parameter: 'ID' und 'NAME'. Um die Parameter zu bestimmen, wird die Abfrage in dem Moment analysiert, wenn der Text von *TSQLQuery.SQL* zugewiesen oder geändert wird. Alle existierenden Parameter werden entfernt und die neuen Parameter zur 'TSQLQuery.Params' Eigenschaft hinzugefügt. Einem Parameter einen Wert zuzuweisen ist ähnlich der Zuweisung eines Werts zu einem Feld im Dataset:
298289
299290``` pascal
300291 Query.Params.ParamByName('Name').AsString := 'Name1';
301292```
302293
303294Sie können der Abfrage mitteilen, welche Art von Daten in dem Parameter gespeichert werden sollen. Der Datentyp des Parameters wird in dem Moment bestimmt, wenn ein Wert das erste Mal dem Parameter zugewiesen wird. Durch die Zuweisung eines Wertes mittels '.AsString', erhält der Parameter den Datentyp 'ftString'. Sie können den Datentyp auch direkt über die 'DataType' Eigenschaft bestimmen. Wenn dem Parameter ein falscher Datentyp zugewiesen wird, dann werden Probleme auftauchen, wenn die Abfrage geöffnet bzw. ausgeführt wird.
304295
305296Das folgende Beispiel erzeugt die selbe Tabelle wie im vorherigen Beispiel, jetzt aber unter Verwendung von Parametern:
306297
307298``` pascal
308299 procedure CreateTableUsingParameters;
309300
310301 var Query : TSQLQuery;
311302 Param_ID,Param_Name: TParam;
312303
313304 begin
314305 Query := GetQuery;
315306 Query.SQL.Text := 'create table TBLNAMES (ID integer, NAME varchar(40));';
316307 Query.ExecSQL;
317308
318309 Query.SQL.Text := 'insert into TBLNAMES (ID,NAME) values (:ID,:NAME);';
319310
320311 Param_ID:=TParam.Create(Query.Params,ptInput);
321312 Param_ID.Name:='ID';
322313 Query.Params.AddParam(Param_ID);
323314
324315 Param_Name:=TParam.Create(Query.Params,ptInput);
325316 Param_Name.Name:='Name';
326317 Query.Params.AddParam(Param_Name);
327318
328319 Query.Params.ParamByName('ID').AsInteger := 1;
329320 Query.Params.ParamByName('NAME').AsString := 'Name1';
330321 Query.ExecSQL;
331322
332323 Query.Params.ParamByName('ID').AsInteger := 2;
333324 Query.Params.ParamByName('NAME').AsString := 'Name2';
334325 Query.ExecSQL;
335326
336327 Query.Close;
337328 Query.Free;
338329 end;
339330```
340331
341332Was sofort auffällt, ist, dass dieses Beispiel mehr Code verwendet, als das Beispiel das keine Parameter verwendet. Was ist dann der Vorteil der Verwendung von Parametern? Einer der Gründe ist Geschwindigkeit. Die meisten Datenbankserver unterstützen Parameter.\
342333Mit 'TSQLQuery.Prepare' bestimmen Sie, dass der Datenbankserver bereits reservierte Ressourcen nutzen soll. Der Aufruf der Methode '.Prepare' ist sinnvoll, wenn Sie mehrere Datensätze auf einmal bearbeiten wollen. Mit 'TSQLQuery.unPrepare' bestimmen Sie, dass der Datenbankserver reservierte Resourcen freigeben soll (Das geschieht automatisch.).\
343334Beispiel für '.Prepare':
344335
345336``` pascal
346337 for i := 1 to j do
347338 begin
348339 Query.paramByName('ID').AsInteger := i;
349340 Query.paramByName('Name').AsString := 'Name...';
350341 Query.Prepare;
351342 Query.ExecSQL;
352343 end;
353344```
354345
355346Ein anderer Grund für die Verwendung von prepared statements ist die Vermeidung von [SQL-Injection](http://de.wikipedia.org/wiki/SQL-Injection). Aber in manchen Fällen vereinfacht es auch nur die Programmierung.\
356347
357348## Siehe auch
358349
359350`* `[[Working With TSQLQuery]]`.`
360351
361352---
362353*From the Free Pascal wiki, page "SqlDBHowto/de", as it stood on 2020-02-27 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history