Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Was sind parametrisierte SQL-Statements und wann anwenden? (https://www.delphipraxis.net/180665-sind-parametrisierte-sql-statements-und-wann-anwenden.html)

jobo 6. Jun 2014 09:05

AW: Was sind parametrisierte SQL-Statements und wann anwenden?
 
Zitat:

Zitat von TRomano (Beitrag 1261539)
ich sehe leider in verschiedenen Projekten Unmengen an String-Operationen, die immer wieder in Schleifen dasselbe SQL-Statement zusammen basteln, um die Parameter zu setzen.
Da gehen Statements bis in den Kilobyte-Bereich und keiner sieht mehr durch.
Es ist dort sinnvoller (aus Performance-Sicht und der Übersichtlichkeit wegen) ein SQL-Statement einmalig zu "basteln" (z.B. in einem Query-Tool) und die dann vielleicht 20 Parameter zu setzen. Das ganze Gedönse der unterschiedlichen Behandlung von Datums-Formaten (z.B.) entfällt auch. :thumb:

:thumb:

Zitat:

Zitat von mkinzler (Beitrag 1261541)
Zitat:

Zitat von joachimd (Beitrag 1261538)
eine Anmerkung noch zu mkinzlers Beispiel: ich würde nicht unbedingt auf Value gehen, sondern direkt mit AsString, AsDate usw arbeiten, damit der zu erwartende Datentyp auchschon im Code klar ist:
Delphi-Quellcode:
Query.ParamByName('vorname').AsString := 'Hans';
Query.Params[1].AsString := 'Mueller';
Query.ParamByName('gebdat').AsDate := ...;
Query.ExecuteSQL;

Dann hat man u.U. aber viele unnötigen Cast-Operationen.

Vielleicht sollte man beim Thema Parameter und Performance 2 Dinge unterscheiden.
Anwendungsperformance (beim Client) und Abfrageperformance (auf der DB).
Bei "einmaligen" Abfragen geht es in erster Linie um die Anwortzeit der DB und die ist weder von der clientseitigen Aufbereitung noch von der Parametrierung abhängig. Genauer, parametriert, typisiert, egal. Die Analyse dürfte vom Laufzeitverhalten nur einen Bruchteil ausmachen, gegenüber dem Aufbau des Datencursors.
Bei "massenhaften" Abfragen sieht es anders aus. Sowohl die Parametrierung im Client (Parameteransprache via Index/Name, ggF. Casts, ..) also auch die Analyse DB seitig werden zum Laufzeitfaktor. "Massenhaft" kann dabei sowohl ein Client auftreten mit einer Query Loop, als auch viele Clients (100, 1000) mit der immer gleichen Gelegenheits-Abfrage.

Der schöne Günther 6. Jun 2014 10:36

AW: Was sind parametrisierte SQL-Statements und wann anwenden?
 
Ich habe mich bis heute immer das gleiche gefragt, jetzt weiß ich endlich auch mit Sicherheit, was Parameter bei Queries sind 8-)

Kann jemand noch ein bisschen aus der Praxis von konkreten Datenbanken erzählen? Ich könnte mir jetzt vorstellen, dass ein DMBS es beispielsweise erlauben würde, den Tabellennamen selbst zu paramatrisieren, ein anderes hingegen nicht. Gibt es da was?

DeddyH 6. Jun 2014 10:51

AW: Was sind parametrisierte SQL-Statements und wann anwenden?
 
Nach meiner Kenntnis kann man grundsätzlich ausschließlich Werte parametrisieren, also weder Datenbank-, Tabellen- noch Feldnamen.

himitsu 6. Jun 2014 11:09

AW: Was sind parametrisierte SQL-Statements und wann anwenden?
 
Also, Parameter sind grundsätzlich erstmal nur Werte.
Namen von Tabellen und Feldern sind aber keine Werte.

Dafür gibt es dann z.B. Makros, bei einigen Komponenten, wie z.B. den xxDAC's.

Delphi-Quellcode:
Query.SQL.Text := 'SELECT AnderesFeld FROM &Table WHERE Feld = :Wert';
Query.MacroByName('Tabelle').Value := 'irgendwas';
Query.ParamByName('Wert').AsString := 'abc';
Query.Open;
ShowMessage(Query.FieldByName('AnderesFeld').AsString);

jobo 6. Jun 2014 11:25

AW: Was sind parametrisierte SQL-Statements und wann anwenden?
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1261579)
Kann jemand noch ein bisschen aus der Praxis von konkreten Datenbanken erzählen? Ich könnte mir jetzt vorstellen, dass ein DMBS es beispielsweise erlauben würde, den Tabellennamen selbst zu paramatrisieren, ein anderes hingegen nicht. Gibt es da was?

Ich kann zu Oracle konkret sagen, die Analyse der Abfrage erfolgt ganz stumpf nach Gleichheit. Ist die Abfrage nicht exakt identisch (select * from customer where nr = 1/select * from customer where nr = 2), sind es zwei verschiedene Abfragen und es werden beide analysiert.
Bei Parametern die dann als Platzhalter im Querytext konstant bleiben, erfolgt die Analyse nur bei der ersten Abfrage.

Dynamische Tabellennamen
Wäre manchmal schön, aber
Das riecht etwas nach verkorkstem Datenmodell ala "ich habe hier alle Kunden, die 2014 dazu gekommen sind in CUSTOMER2014 und dann in tabelle CUSTOMER2013 die von .. ".
Es bedeutet im Prinzip, dass ich gleiche Strukturen vorsehe und ein Merkmal aber im Tabellenname definiere und das ist meistens schlecht.
Es gibt bei Oracle eine API mit der man dynamisch SQL konstruierten kann, aber das ist wohl ein Thema für sich.

Dejan Vu 6. Jun 2014 12:21

AW: Was sind parametrisierte SQL-Statements und wann anwenden?
 
Zitat:

Zitat von mkinzler (Beitrag 1261541)
Zitat:

Zitat von joachimd (Beitrag 1261538)
.. sondern direkt mit AsString, AsDate usw arbeiten, damit der zu erwartende Datentyp auch schon im Code klar ist

Dann hat man u.U. aber viele unnötigen Cast-Operationen.

Den Einwand verstehe ich nicht. Man hat gerade keine Cast-Operationen, und damit auch keine Unnötigen.
Delphi-Quellcode:
myQuery.ParamByName('Foo').Value := a;
myQuery.ParamByName('Bar').Value := b;
// vs
myQuery.ParamByName('Foo').AsString := a;
myQuery.ParamByName('Bar').AsDateTime := b;
Bezüglich der Feldnamen/Tabellen als Parameter: Wenn ich mir meine WHERE-Klausel dynamisch zusammenbauen will, wäre das vielleicht ganz praktisch, aber da muss man eben direkt an die Query ran. So wild ist das ja nun auch nicht.

TRomano 6. Jun 2014 12:39

AW: Was sind parametrisierte SQL-Statements und wann anwenden?
 
Zitat:

von Dejan Vu
myQuery.ParamByName('Foo').Value := a;
myQuery.ParamByName('Bar').Value := b;
// vs
myQuery.ParamByName('Foo').AsString := a;
myQuery.ParamByName('Bar').AsDateTime := b;
In deinem Beispiel beschreibst Du genau das Problem: Deinen Feldnamen sind 'Foo' und 'Bar' und woher soll man wissen, was wirklich hinter den Feldnamen an Typen steckt. Sollte mal ein anderer Entwickler an deinen Source ran ... viel Glück !
Im zweiten Teil ist es klarer und verständlicher ...

TRomano 6. Jun 2014 12:48

AW: Was sind parametrisierte SQL-Statements und wann anwenden?
 
Und noch etwas fällt mir sehr oft auf: in großen Query-Loops wird gerne mit .FieldByName(..) oder ParamByName(..) gearbeitet. Den letzten "Rekord", den ich da sah waren ca. 30.000 Loops über 38 Felder jeweils mit .FieldByName(..) !!! Da kann man auch entweder über den DataSet-Editor persistente Felder anlegen oder eben Variablen nach dem Muster oFldName := DataSet.FieldByName('Name') anlegen. Erstens kann man Laufzeitzeiter-Fehler abfangen (if (oFldName = nil) und zweitens wird man mit einem nicht unerheblichen Performance-Plus belohnt ... oder optimiert der Delphi-Compiler so etwas weg :wink::thumb:

Gruß Thomas

himitsu 6. Jun 2014 13:05

AW: Was sind parametrisierte SQL-Statements und wann anwenden?
 
Zitat:

Zitat von TRomano (Beitrag 1261600)
Im zweiten Teil ist es klarer und verständlicher ...

Und der Compiler prüft auch die zugewiesenen Typen.

Ja, bei Schleifen, kommt man besser, wenn man sich die Felder vorher besorgt, falls das die Komponente nicht gleich bietet.
Einige Query-Komponenten (auf der Form abgelegt) bieten die Möglichkeiten die ensprechenden Feld-/Paramer-Komponenten (TField/TParam) direkt erstellen zu lassen.

Delphi-Quellcode:
Query.Insert;
QueryFeldA.AsString := '123'; // bzw. Query.FeldA.AsString := '123';
Query.Post;
statt
Delphi-Quellcode:
Query.Insert;
Query.FieldByName(FeldA).AsString := '123';
Query.Post;
Das gibt im Code nochmal einen Schritt mehr, in punkto Codesicherheit, da hier der Compiler die hingeschriebenen Komponentennamen prüfen kann, ob es das TField auch gibt
und die Codevervollständigung schlägt einem die Namen ebenfalls vor.

Entsprechendes gilt z.B. auch für die ORMs.





Nja, selbst wenn man nicht das Performance-Plus ausnutzt und wenn man oft im Code irgendwelche Queries aufruft, dann kann man dennoch nummerierte Parameter benutzen.

Delphi-Quellcode:
with x.LoadSql('SELECT * FROM tabelle WHERE feld = :param', ['abc']) do
  try
    while not EoF do begin
      // mach was, mit FieldByName['xxx']
      Next;
    end;
  finally
    Free;
  end;

S := x.GetStr('SELECT xxx FROM tabelle WHERE feld = :param AND x <> :x', ['abc', 3]);
ShowMessage(S);
So ist der Code immernoch übersichtlicher und fehlerunanfälliger, als wenn da erst der SQL-String wirr zusammengemanscht wird.

Das Parameter-Array kann dabei z.B. die SQL-Parameter in der Reihenfolge der benutzen Namen enthalten, gefolgt von eventuellen Makros.

Dejan Vu 6. Jun 2014 13:19

AW: Was sind parametrisierte SQL-Statements und wann anwenden?
 
Zitat:

Zitat von TRomano (Beitrag 1261600)
Im zweiten Teil ist es klarer und verständlicher ...

Gerade *DAS* meinte ich ja!


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

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