Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Insert-Statement nicht verstanden (https://www.delphipraxis.net/209433-insert-statement-nicht-verstanden.html)

HerWin 6. Dez 2021 18:52

Datenbank: sqlite • Version: 3.36 • Zugriff über: Firedac

Insert-Statement nicht verstanden
 
Hallo,
ich möchte eine SQLite-Datenbank mit Firedac nutzen.
Dazu habe ich mir das Beispiel GettingStarted aus Delphi 10.4 geladen.
Hier gibt es einen SQL Insert-Befehl, den ich nicht verstehe:

'insert into Categories(CategoryName, Description, Picture) ' +
'values(:N, :D, :P)', ['New category', 'New description', $0334])

Was bedeuted hier values(:N, :D, :P)?

Ich gehe davon aus, das sind die Feldnamen im DBGrid. Aber wo werden die
definiert? In der Datenbank stehen die richtigen Feldnamen (CategoryName...)
Ich kann, auch nach heftigem Suchen, nichts finden.
Leider gibt die Delphi-Beschreibung dazu nichts her.

Wenn mir das jemand erklärt, wäre ich dankbar.

DeddyH 6. Dez 2021 19:31

AW: Insert-Statement nicht verstanden
 
Es handelt sich um SQL-Parameter. Damit kann man sein Statement einmalig deklarieren und muss lediglich die Parameterwerte neu belegen, wenn man z.B. mehrere Datensätze in einem Rutsch anlegen möchte. Ein weiterer Vorteil ist, dass Parameterwerte automatisch passend zum Typ maskiert werden, man schützt sich damit ganz nebenbei vor SQL-Injection.

HerWin 6. Dez 2021 20:09

AW: Insert-Statement nicht verstanden
 
Hallo DeddyH,
danke für die Antwort. Ich habe es aber immer noch nicht verstanden.

Woher kommen die Buchstaben N, D und P?

Sollen das Datentypen sein? N = Numerisch, D = Dezimal? P = ???
Sind das einfach nur beliebige Bezeichner, die der Reihe nach abgearbeitet werden?

Wozu brauche ich das hier, wenn nur ein Datensatz verarbeitet wird (Schutz vor SQL-Injection)?

VG

DeddyH 6. Dez 2021 20:14

AW: Insert-Statement nicht verstanden
 
Ein SQL-Parameter beginnt immer mit einem Doppelpunkt. Danach kann jeder gültige Bezeichner kommen, den kannst Du frei vergeben. In diesem Beispiel könnte man theoretisch auch auf Parameter verzichten, müsste dann aber beispielsweise String-Werte selber quoten. Im realen Leben ist es aber meist eher so, dass die Werte eben nicht hartkodiert im Code stehen, sondern aus Benutzereingaben stammen. Diese sind grundsätzlich als potenziell gefährlich zu betrachten, da ist es äußerst wichtig, sich gegen SQL-Injection zu schützen.

HerWin 6. Dez 2021 20:16

AW: Insert-Statement nicht verstanden
 
Vielen Dank,

das muß ich mir ansehen.

Guido R. 7. Dez 2021 00:35

AW: Insert-Statement nicht verstanden
 
Hallo HerWin!
Zitat:

Sollen das Datentypen sein? N = Numerisch, D = Dezimal? P = ???
Mein Tipp anhand des SQL-Befehls ist eher N = CategoryName, D = Description, P = Picture

Medium 7. Dez 2021 01:23

AW: Insert-Statement nicht verstanden
 
Um die Verwendung im Code zu verdeutlichen:

Delphi-Quellcode:
Query1.SQL.Text := 'INSERT INTO Categories (CategoryName, Description, Picture) VALUES (:N, :D, :P)';
Query1.ParamByName['N'].AsString := 'New category';
Query1.ParamByName['D'].AsString := 'New description';
Query1.ParamByName['P'].AsInteger := $0334;
Query1.Execute;
Das würde genau das ausführen, was du in deinem Beispiel gezeigt hast. Die möglichen Vorteile wurden ja bereits von DeddyH genannt. Zudem empfinde ich es schlicht als besseren Stil Parameter zu nutzen, statt umständlich in Strings umgewandelte und ''gequotedte'' Ausdrücke zu nehmen.

Man könnte die Parameter allerdings noch sprechender benennen für meinen Geschmack. Auch kann man sie statt mit ParamByName() indiziert via Params[i] referenzieren, finde ich aber nicht so schön, da dann die Reihenfolge im SQL-Statement wichtig wird. Man kann übrigens auch denselben Parameter mehrmals im selben SQL-Statement verwenden, was in manchen Fällen auch praktisch sein kann.

himitsu 7. Dez 2021 02:36

AW: Insert-Statement nicht verstanden
 
Hier war einfach nur wer schreibfaul, oder wollte Speicher sparen, und es geht natürlich auch länger:
Delphi-Quellcode:
Query1.SQL.Text := 'INSERT INTO Categories (CategoryName, Description, Picture) VALUES (:CategoryName, :Description, :Picture)';
Query1.ParamByName['CategoryName'].AsString := 'New category';
Query1.ParamByName['Description'].AsString := 'New description';
Query1.ParamByName['Picture'].AsInteger := $0334;
Query1.Execute;
Und da die Parameternamen grundsätzlich egal sind:
Delphi-Quellcode:
Query1.SQL.Text := 'INSERT INTO Categories (CategoryName, Description, Picture) VALUES (:mvsdnjkfdsa, :gbvös, :jmnfkeads)';
Query1.ParamByName['mvsdnjkfdsa'].AsString := 'New category';
Query1.ParamByName['gbvös'].AsString := 'New description';
Query1.ParamByName['jmnfkeads'].AsInteger := $0334;
Query1.Execute;
Es gibt auch Statements/DBMS/Datenbankkompoenten, die garkeine Namen nutzen, sondern nur durchnummerieren, wie z.B.
Delphi-Quellcode:
Query1.SQL.Text := 'INSERT INTO Categories (CategoryName, Description, Picture) VALUES ($0, $1, $2)';
Query1.Params[0].AsString := 'New category';
Query1.Params[1].AsString := 'New description';
Query1.Params[2].AsInteger := $0334;
Query1.Execute;
Wobei das .Params[123] natürlich auch bei den oberen Varianten im Programm genutzt werden kann.


Bei deinem Beispiel werden die Namen auch nicht verwendet, sondern einfach mit dem Array
Delphi-Quellcode:
['New category', 'New description', $0334]
nacheinander die Parameter gefüllt werden, egal wie sie heißen.

haentschman 7. Dez 2021 07:05

AW: Insert-Statement nicht verstanden
 
Moin...8-)
Zitat:

sondern einfach mit dem Array ['New category', 'New description', $0334]
...imho kann es aber auch Komponenten geben, die die overload Variante mit dem Array nicht kennen. :? Deshalb würde ich eher die klassische Variante empfehlen.
Delphi-Quellcode:
Query1.SQL.Text := 'INSERT INTO Categories (CategoryName, Description, Picture) VALUES (:CategoryName, :Description, :Picture)';
Query1.ParamByName['CategoryName'].AsString := 'New category';
Query1.ParamByName['Description'].AsString := 'New description';
Query1.ParamByName['Picture'].AsInteger := $0334;
Query1.Execute;
SQL Injection: https://de.wikipedia.org/wiki/SQL-Injection

TigerLilly 7. Dez 2021 12:37

AW: Insert-Statement nicht verstanden
 
Aufpassen! Der TE hat zu reinem SQL gefragt, da sind keine Komponenten im Spiel. Und die Frage bezog sich NUR auf die Namensgebung + das wurde sinngemäß ja beantwortet.

Code:
insert into Categories(CategoryName, Description, Picture) values(:N, :D, :P), ['New category', 'New description', $0334])
insert into Categories(CategoryName, Description, Picture) values(:Category, :Description, :Picture), ['New category', 'New description', $0334])
insert into Categories(CategoryName, Description, Picture) values(:stgt, :wrth, :wertb), ['New category', 'New description', $0334])
Tun alle das gleiche.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:03 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz