Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi SQL Abfrage Formulieren! Hilfe... (https://www.delphipraxis.net/21027-sql-abfrage-formulieren-hilfe.html)

celinaw 26. Apr 2004 23:58


SQL Abfrage Formulieren! Hilfe...
 
Hi

Ich möchte aus einer Tabelle die Daten eines bestimmten Zeitraums haben.
Wie formuliert man so eine Abfrage in SQL?

Das Datumsfeld in der SQl DB heißt "First_Event" und ist ein Date/Time! Also "2004-04-26 22:00:00"

Anfangsdatum und Enddatum stehen in den Editfeldern (edBegenn und edEnde).

:gruebel: 'Select * From ordertracking ...........' :gruebel:

Weiß einer wie es geht?

Gruß celina

celinaw 27. Apr 2004 00:25

Re: SQL Abfrage Formulieren! Hilfe...
 
Hier mein Aktueller Code....


Delphi-Quellcode:
    qrMain.SQL.Text :=
  'SELECT ' +
    'T.Order_Type,' +
    'T.Customer_Number,' +
    'T.Order_Number,' +
    'T.First_Event,' +
    'T.LogIn,' +
    'T.DPrint,' +
    'T.Count_DPrint,' +
    'T.Invoicing,' +
    'T.PrePrint,' +
    'T.Print,' +
    'T.Cewe_Batch,' +
    'T.Iqena_Batch,' +
    'T.BMSLogout,' +
    'K.Na,' +
    'K.Customer_Number,' +
    'K.Str,'+
    'K.Ort,' +
    'K.Tel,' +
    'K.PFD,' +
    'K.Fach_TAG,' +
    'K.Fach_NAcht,' +
    'K.Ap,' +
    'K.PLZ ' +
  'FROM ' +
    'table_ordertracking T,' +
    'kundenmg K ' +
  'WHERE ' +
    'T.Customer_Number=K.Customer_Number ' +
    'AND ' +
    'T.First_Event like ''' + edknr.Text + '''"%" ' +
    'AND ' +
    'T.First_Event like ''' + edatnr .Text + '''"%" ' +
  'ORDER BY ' +
    'T.First_Event;';

     qrMain.Open;
[edit=Luckie]Delphi-Tags gefixed. Mfg, Luckie[/edit]

mikhal 27. Apr 2004 05:35

Re: SQL Abfrage Formulieren! Hilfe...
 
Versuch mal folgendes:
Delphi-Quellcode:
...
'WHERE T.FIRST_EVENT BETWEEN ' + StrToDate(EdBegenn.Text) + ' AND ' + StrToDate(EdEnde.Text)
...
Ansonsten verwende parametriesiertes SQL:
Delphi-Quellcode:
...
'WHERE T.FIRST_EVENT BETWEEN :ANFANG AND :ENDE
...
qryMain.PREPARE;
...
qryMain.Parameters[0].Value := StrToDate(EdBegenn.Text);
qryMain.Parameters[1].Value := StrToDate(EdEnde.Text);
qryMain.Open;
...
Schau dir dazu mal die Parameterverarbeitung in der Hilfe an, das Beispiel sollte mit TADOQuery funktioneren. Vorteil ist, daß du das SQL-Statement bereits im Objektinspektor festlegen kannst und dann in deinem Quelltext nur noch die Parameter zuweisen mußt. Sicherer ist dieser Code obendrein.

Grüße
Mikhal

nieurig 27. Apr 2004 06:28

Re: SQL Abfrage Formulieren! Hilfe...
 
Guten Morgen Celina und Mikhal,

Zitat:

Sicherer ist dieser Code obendrein
Ich denke Parameter sind bei Datumsfeldern eigentlich ein Muß. Die Alternative mit dem zusammengesetzten String funktioniert nämlich nicht bei allen Datenbanken, weil die Schreibweise eines Datums unterschiedlich ist.

MS-SQL Server will z.B. folgendes Format: '23.12.2004'
Access will es so: #23.12.2004#
MYSQL akezptiert nur die Ami-Schreibweise 12.23.2004 (oder so ähnlich).

Wenn Du Parameter verwendest kümmert sich Delphi drum.

Schöne Grüße
Niels

Delphi_Fanatic 27. Apr 2004 06:36

Re: SQL Abfrage Formulieren! Hilfe...
 
Das Datum und die Zeit wird windows-intern als Integer gespeichert.

TDateTime ist im Prinzip mit dem Typ Double identisch, wobei dann links vom Komma der
Datums-Integer und rechts davon der Zeit-Integer steht.

Also alles, was Du tun mußt, ist in einem TDateTime-Wert den Datums-Integer zu
isolieren, und den kannst Du dann auch in Deinem SQL-Query verwenden, also
z.B. 'where T.irgendeindatum = ' + inttostr(datumsinteger)

Leuselator 27. Apr 2004 07:02

Re: SQL Abfrage Formulieren! Hilfe...
 
@Delphi_Fanatic: damit kannst Du aber heftig auf die Fresse fallen, weil es durchaus unterschiedliche Basisdaten für den Datumsinteger gibt. So ist z.B. für Delphi die Basis der 30.12.1899, für MSSQL dagegen ist es der 01.01.1900 - das macht schonmal 2 Tage Unterschied!

@celinaw: lass Dich daher nicht beirren - Parameter für Datum'se sind die einzig vernünftige Art!

Gruß

Sharky 27. Apr 2004 08:13

Re: SQL Abfrage Formulieren! Hilfe...
 
Zitat:

Zitat von Leuselator
...- Parameter für Datum'se sind die einzig vernünftige Art!..

Nicht nur für das Datum finde ich.
Aber das Datum macht immer am meisten Sorgen :? mySQL gibt es z.B. immer so zurück yyyy-mm-dd
Wenn ich dann im Programm einfach .AsDateTime := now schreibe habe ich (zumindest mit den Zeos-Komponenten) probleme.

Delphi_Fanatic 27. Apr 2004 09:01

Re: SQL Abfrage Formulieren! Hilfe...
 
@Leuselator

Zitat:

@Delphi_Fanatic: damit kannst Du aber heftig auf die Fresse fallen, weil es durchaus unterschiedliche Basisdaten für den Datumsinteger gibt. So ist z.B. für Delphi die Basis der 30.12.1899, für MSSQL dagegen ist es der 01.01.1900 - das macht schonmal 2 Tage Unterschied!
na ja, aber Tatsache ist, dass Delphi intern denselben Integer für eine Datums-Angabe verwendet wie Windows. Delphi bezieht diesen integer ja auch vom Windows-System.

Und Microsoft-Produkte wie Access-Datenbanken machen es genauso, so dass es zumindestens in Verbindung mit diesen Datenbank-Systemen auf jeden Fall funktioniert.

Falls es da bei anderen DB-Systemen wie Paradox, Oracle usw... Unterschiede geben sollte - dann müssen die ja so oder so berücksichtigt werden, auch bei den anderen Methoden, die hier gepostet wurden wie z.B. 'qryMain.Parameters[0].Value := StrToDate(EdBegenn.Text);', denn die Delphi-Funktion StrToDate bezieht sich schließlich auch auf den Windows-Datums-Integer und nicht irgendwelche Paradox- oder sonstige Spezialitäten.

Robert_G 28. Apr 2004 21:07

Re: SQL Abfrage Formulieren! Hilfe...
 
@Delphi_Fanatik
Wie kommst du auf die Idee TDate sei ein Integer?
Mein D7 sagt mir immer noch das:
Delphi-Quellcode:
  TDateTime = type Double;
  ...
  TDate = type TDateTime;
...und zukünftig gilt nur noch das:
Zitat:

Zitat von .Net SDK Doku
The DateTime value type represents dates and times with values ranging from 12:00:00 midnight, January 1, 0001 Anno Domini (Common Era) to 11:59:59 P.M., December 31, 9999 A.D. (C.E.)

Time values are measured in 100-nanosecond units called ticks, and a particular date is the number of ticks since 12:00 midnight, January 1, 1 A.D. (C.E.) in the GregorianCalendar calendar. For example, a ticks value of 31241376000000000L represents the date, Friday, January 01, 0100 12:00:00 midnight. A DateTime value is always expressed in the context of an explicit or default calendar.

Da wird man mit einem Integer (jedenfalls Int32) auch nicht weit kommen...
Das Datumsfelder (wie eigentlich jeder Wert) in einen Parameter gehört wurde wohl nicht nur in diesem Thread oft genug gepredigt.

@Sharky
Delphi-Quellcode:
with Query do
begin
  SQL.Text :=
    'SELECT X' + #10 +
    'FROM  Y' + #10 +
    'WHERE Z = :i_XYZ';
  with Parameters.ParamByName('i_XYZ') do
  begin
    DataType := ftDateTime;
    Value := now;
  end;
  Open;
  //...
end;
Dieser Vergleich kann nur funktionieren wenn Z auf die Millisekunde (unter .Net auf 100 Nanosekunden) mit der aktuellen Systemzeit übereinstimmt. Im Normalfall sollte man bei direkten Vergleich den Zeitanteil abschneiden.

Delphi_Fanatic 29. Apr 2004 07:17

Re: SQL Abfrage Formulieren! Hilfe...
 
@Robert_G :

Zitat:

Wie kommst du auf die Idee TDate sei ein Integer?
Also nochmal : Windows verwaltet das Datum intern als Integer.
Kannst Du ganz leicht ausprobieren : Starte Excel, gib' in irgendeine Zelle das heutige Datum ein - den
29.04.2004 - und dann Pulldown-Menü 'Format / Zellen' und klick da auf Zahl.
Dann siehst Du in dieser Excel-Zelle die windows-interne Ganz-Zahl, die für den 29.04.2004 steht,
nämlich 38106.

Und wenn Du nun in Delphi das Datum abfragst, dann steht in dem Datentyp TDateTime (der wie gesagt
dem Datentyp Double entspricht) "links" vom Komma dieser Ganz-Zahl-Wert für das Datum, den Delphi
vom Windows-System bezieht (für heute 38106) und "rechts" vom Komma steht ein Ganz-Zahl-Wert, der die Zeit repräsentiert.
Wenn Du Dir dann die Datums-Zahl links vom Komma 'isolierst' erhälst Du einen Integer-Wert, der für das Datum steht
und das Du locker im Zusammenhang mit SQL-Queries verwenden kannst. Jedenfalls bei Microsoft-Datenbanken wie Access.

TDateTime ist natürlich kein Integer, aber das Datum an sich, wird durch eine ganze Zahl repräsentiert und kann ganz
einfach aus dem TDateTime extrahiert werden - undzwar in eine integer-Variable.

Robert_G 29. Apr 2004 07:22

Re: SQL Abfrage Formulieren! Hilfe...
 
:gruebel:
Das hatte ich wohl gestern abend nach 5 1/2 h ICE-Fahrt falsch verstanden.
Sorry, falls es zu barsch klang...

nieurig 29. Apr 2004 12:39

Re: SQL Abfrage Formulieren! Hilfe...
 
Hi Delphi_fanatic,

Zitat:

Also nochmal : Windows verwaltet das Datum intern als Integer.
ich glaube das nicht.

Zitat:

Kannst Du ganz leicht ausprobieren : Starte Excel, gib' in irgendeine Zelle das heutige Datum ein - den
29.04.2004 - und dann Pulldown-Menü 'Format / Zellen' und klick da auf Zahl.
Dann siehst Du in dieser Excel-Zelle die windows-interne Ganz-Zahl, die für den 29.04.2004 steht,
nämlich 38106.
Gib in Excel mal "29.4.2004 10:23" ein und ändere das Format, und Du bekommst einen Floatwert. Wenn Du nur ein Datum eingibst speichert Excel die Uhrzeit 00:00 und stellt den Zahlenwert als Int dar.

Klar, der Vorkommateil ist das Datum und durch eine Umwandlung von Float in Int hast Du das Datum. Die interne Verwaltung bleibt trotzdem ein Float, bei dem eben der Nachkommateil die Uhrzeit darstellt.

Niels

Leuselator 29. Apr 2004 13:08

Re: SQL Abfrage Formulieren! Hilfe...
 
@Delphi_Fanatic: Du solltest vorsichtig mit allgemeingültigen Aussagen wie:
Zitat:

und das Du locker im Zusammenhang mit SQL-Queries verwenden kannst. Jedenfalls bei Microsoft-Datenbanken wie Access.
sein, da der MSSQL-Server eben einen anderen (+2Tage) Datetime-Startwert oder Ausgangspunkt hat als MS-Windows und somit Probleme bei Deinem vorgeschlagenen Weg unausweichlich sind.

Man kann mit Datumswerten in der von Dir genannten Weise operieren, allerdings sollte man eben genau wissen, was intern abgeht.

Gruß

Gollum 29. Apr 2004 13:39

Re: SQL Abfrage Formulieren! Hilfe...
 
Hallo,

das Datum wird bei allen Datenbanken und bei Windows als Fließkommazahl behandelt, da sonst kein Zeitanteil mit übergeben werden kann.

Zitat:

Zitat von nieurig
Wenn Du Parameter verwendest kümmert sich Delphi drum.

Das stimmt so nicht.

Ich habe mir dafür extra Funktionen geschrieben, die das Datum in die entsprechende Schreibweise für die verschiedenen DB's umwandelt.

@celinaw
Folgendes sollte funktionieren:
Delphi-Quellcode:
function FmtDateMySQL(const aDate:TDateTime; const withTime:Bool=False);
var t, m, j, std, min, sek, hs:Word;
begin
  DecodeDate(aDate, j, m, t);
  if (withTime)
  begin
    DecodeTime(aDate, std, min, sek, hs);
    Result:=Format('%d-%0.2d-%0.2d %0.2d:%0.2d:%0.2d', [j, m, t, std, min, sek]);
  end else Result:=Format('%d-%0.2d-%0.2d', [j, m, t]);
end; // FmtDateMySQL
Für Dein Beispiel:
Delphi-Quellcode:
qryMain.Parameters[0].Value := FmtDateMySQL(StrToDate(EdBegenn.Text));
qryMain.Parameters[1].Value := FmtDateMySQL(StrToDate(EdEnde.Text));

Delphi_Fanatic 29. Apr 2004 13:54

Re: SQL Abfrage Formulieren! Hilfe...
 
@Leueselator :

Zitat:

sein, da der MSSQL-Server eben einen anderen (+2Tage) Datetime-Startwert oder Ausgangspunkt hat als MS-Windows und somit Probleme bei Deinem vorgeschlagenen Weg unausweichlich sind.
MS SQL-Server ist weder von mir, noch vom Thread - Eröffner explizit erwähnt worden.
Trotzdem würde mich jetzt mal interessieren :
An welcher Stelle wird denn diese '+2-Konvertierung' automatisch vorgenommen, wenn man einen Datums-Wert an einen query.parameter übergibt ?

Zitat:

allerdings sollte man eben genau wissen, was intern abgeht.
Ich lasse mich gerne 'eines Besseren belehren', aber Tatsache ist doch, dass der Datums-Integer, der im Delphi-Programm abgegriffen wird, definitiv immer derselbe ist. Egal, ob man ihn nach der von mir beschriebenen Möglichkeit oder nach irgendeiner anderen Möglichkeit abgreift.

Die Quelle bzgl. dieses Datums-Wertes ist in jedem Falle doch dieselbe. Lediglich das Ziel war bei mir ein Anderes : Ich wollte den Datums-Integer direkt in SQL.Text reinschreiben, Du wolltest den Weg über Query.Parameter gehen.

Also wenn bei der Benutzung von Query.Parameter automatisch irgendwo diese +2-Konvertierung statt findet - dann hättest Du natürlich recht... ansonsten müßtest Du diese Konvertierung doch bei beiden Methoden machen ...

Robert_G 29. Apr 2004 14:11

Re: SQL Abfrage Formulieren! Hilfe...
 
Zu einer vernünftigen DB, gibt es vernünftige native Zugriffsmöglichkeiten oder OLE DB Treiber.
Diese wandeln das Datum entsprechend um. Während der MS SQL Svr irgendwann 1899 oder so anfängt macht es Oracle ähnlich wie .Net (nur das es ein Byte pro Segment bzw. Integer für das Jahr ist).
Wichtig ist doch dabei nur, dass hinten das rauskommt, was verlangt wird...

Ich glaube Gollum hat schon eine Lösung für Celinas Problem gepostet.
Auch wenn ich es generell für nicht sinnvoll halte in einem Datum mit dem Like operator zu suchen. :? (Es wird in 90% aller Anfragen nach irgendwelchem Käse gesucht und gefunden werden die Löcher :P )

Diese ganze Integer/Double/DateTime-Diskussion war wohl schon OT & aussichtslos als sie angefangen hatte... :mrgreen:

Sharky 29. Apr 2004 14:15

Re: SQL Abfrage Formulieren! Hilfe...
 
Zitat:

Zitat von Robert_G
...war wohl schon OT & aussichtslos als sie angefangen hatte...

Und darum bitte ich alle sich wieder direkt mir der Frage zu beschäftigen und, wenn es denn notwendig ist, für diese Diskussion einen entsprechenden Thread zu starten.

Danke :-D

celinaw 30. Apr 2004 00:04

Re: SQL Abfrage Formulieren! Hilfe...
 
Hi :hello:

Nach langem ausprobieren hab ich es endlich hin bekommen :mrgreen:

Ich habe mehrere Lösungen ausprobiert!

Das von Mikhal funktioniert nur wenn man im Editfeld das Datum wie folgt schreibt: 2004-04-24
Zitat:

'WHERE T.FIRST_EVENT BETWEEN ' + StrToDate(EdBegenn.Text) + ' AND ' + StrToDate(EdEnde.Text)

Was bissher Problemlos läuft ist der Code von Gollum!
Zitat:

function FmtDateMySQL(const aDate:TDateTime; const withTime:Bool=False);
var t, m, j, std, min, sek, hs:Word;
begin
DecodeDate(aDate, j, m, t);
if (withTime)
begin
DecodeTime(aDate, std, min, sek, hs);
Result:=Format('%d-%0.2d-%0.2d %0.2d:%0.2d:%0.2d', [j, m, t, std, min, sek]);
end else Result:=Format('%d-%0.2d-%0.2d', [j, m, t]);
end; // FmtDateMySQL



Ich hatte nur so einige Probleme mit den Parametern. Habs aber dann nach einigem lesen und probieren hin bekommen.


Euch allen kann ich nur sagen:

Vielen Vielen Dank für die Hilfe :mrgreen:


Gruß Celina


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:08 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