Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Library: Datenbanken (https://www.delphipraxis.net/22-library-datenbanken/)
-   -   Delphi DateTime-Konstanten in SQL-Anweisungen benutzen (https://www.delphipraxis.net/18959-datetime-konstanten-sql-anweisungen-benutzen.html)

shmia 26. Mär 2004 16:48


DateTime-Konstanten in SQL-Anweisungen benutzen
 
Bei SQL-Abfragen bringt ein Datums oder Zeitfeld
häufig Probleme ins Haus, da in SQL das Format nicht definiert
wurde und jeder DBMS-Hersteller sein eigenes Süppchen kocht.
Daher muss man Datums/Zeitwerte in Parametern übergeben und die
Treiber sorgen im Hintergrund für die richtige Umwandlung.

Was aber tun, wenn die SQL-Abfrage dynamisch vom Benutzer/Programm
erzeugt wird ?

Zumindest für den MS SQL-Server und für MS Access gibt es hier eine
Lösung.
Folgende Funktionen arbeiten unabhängig von eingestellten Datums-/Zeitformat.


Delphi-Quellcode:
function DateTimeToSQLServerDateTimeString(value: TDateTime):string;
begin
  Result := '{ ts'+QuotedStr(FormatDateTime('yyyy-mm-dd hh":"nn":"ss.z', value))+' }';
end;

function DateTimeToSQLServerDateString(value: TDateTime):string;
begin
  Result := '{ d'+QuotedStr(FormatDateTime('yyyy-mm-dd', value))+' }';
end;

function DateTimeToSQLServerTimeString(value: TDateTime):string;
begin
  Result := '{ t'+QuotedStr(FormatDateTime('hh":"nn":"ss.z', value))+' }';
end;


procedure CharReplace(var S: AnsiString; const Search, Replace: AnsiChar);
var
  i : Integer;
begin
  for i := 1 to Length(S) do
    if S[i]=Search then
      S[i]:=Replace;
end;

function DateTimeToAccessDateTimeString(value: TDateTime):string;
begin
  // Da Access (Jet-Engine) ein Datum als Double speichert...
  Result := FloatToStr(value);
  CharReplace(Result, ',', '.');
end;
Hier noch ein Beispiel für den SQL-Server:

Delphi-Quellcode:
// Zeige Aufträge geliefert innerhalb der letzten 30 Tage
Query1.SQL.Text := 'SELECT * FROM Auftrag';
Query1.SQL.Add('WHERE Lieferdatum>'+DateTimeToSQLServerDateTimeString(now-30.0);
[edit=Matze]Code formatiert. Mfg, Matze[/edit]

Robert_G 26. Mär 2004 17:17

Re: DateTime-Konstanten in SQL-Abfragen benutzen
 
Mal eine Frage...
Welchen Vorteil versprichst du dir oder einem unschuldigen CodeLib-Leser von dieser Vorgehensweise?
Mit jedem Aufruf ändert sich der Code des Statements...
SQL-Code:
...
WHERE Lieferdatum>#12.12.2004 12:30:30#
...
WHERE Lieferdatum>#12.12.2004 12:30:00#
...
WHERE Lieferdatum>#12.12.2004 12:29:30#
... und schon muss das Statement neu geparst, ein neuer Cursor geöffnet und die Ganze Geschichte neu abgefragt werden!
Mit dieser Vorgehensweise reduziert man jede hochoptimierte Datenbank zu einem Paradox, dBase oder Access!
Die DB kann ihren Statement- & Cursor- Cache nur benutzen, wenn das Statement absolut gleich bleibt. Das heißt du musst variable Werte auch als Variablen übergeben!
Diese 2 genialen Caches machen einen großen Teil der Performance dieser DBs aus.

Ist das denn so schlimm Parameter zu verwenden?
SQL-Code:
...
WHERE Lieferdatum> :i_LieferDatum

Ich habe dieses Problem bestimmt schon 30+ mal hier in der DP beschrieben!

Ich stimme deshalb mit einem klaren NEIN gegen die Aufnahme dieser Lösung in die CodeLib.

shmia 26. Mär 2004 18:03

Re: DateTime-Konstanten in SQL-Abfragen benutzen
 
Zitat:

Zitat von Robert_G
Mal eine Frage...
Welchen Vorteil versprichst du dir oder einem unschuldigen CodeLib-Leser von dieser Vorgehensweise?
Mit jedem Aufruf ändert sich der Code des Statements...

Diese Vorgehensweise ist für den Fall gedacht, das der Benutzer
bestimmte Anfragen stellen möchte und die Anwendung die SQL-Abfrage
dynamisch zur Laufzeit zusammenbauen muss.
Ausserdem kann die generierte SQL-Abfrage gespeichert (z.B. in Datei
AuftragsbestandJan2004.SQL )
und später wieder geladen werden.

Die Beschleunigung der SQL-Abfragen durch einen Statement-Cache ist dabei
nicht so wichtig, da die Abfrage nur ein oder zweimal gestellt wird.

Für Abfragen, die nicht dynamisch aufgebaut werden, kommt diese Vorgehensweise
natürlich nicht in Betracht. Hier würde man eine Query auf das Formular/Datenmodul
ziehen und eine SQL-Anweisung mit Parametern zur Entwicklungszeit angeben.

Ich benutze diese Konvertierungs-Funktionen auch für den Export eines Datasets in
SQL-INSERT Statements.
Man kann sich z.B. an Datenbank A aus Tabelle Test eine Text-Datei mit
INSERT-Anweisungen erzeugen lassen und an Datenbank B wieder einspielen.
Siehe mein Programm ADO-Desk.

Ich hätte vielleicht als Beispiel nicht eine SELECT Abfrage, sondern
eine INSERT oder UPDATE Anweisung wählen sollen.

Delphi-Quellcode:
Connection.Execute('UPDATE Auftrag SET LieferDatum='+DateTimeToSQLServerDateTimeString(now));


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:33 Uhr.

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