Autor Beitrag
Hänsel
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 144



BeitragVerfasst: So 08.11.15 10:21 
Hallo habe wieder mal ein Problem,

ich möchte aus der Datenbank alle Datensätze anzeigen lassen, welche zwischen den 1. und dem 2. Datum liegen. Habe es mit verschiedenen Varianten (') versucht. Geht nicht.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
var en,bn : TDate;
begin
   en:=DateTimePicker1.Date;
   bn:=DateTimePicker2.Date;


   Datamodule3.ADOQuery_OMDE.close;
   Datamodule3.ADOQuery_OMDE.SQL.Text:='Select * From OBJ where Abl_Tag Between ('''+en+''') and ('''+bn+''')';
   Datamodule3.ADOQuery_OMDE.open;
end;

Wer kann mir hier weiter helfen?

Im Voraus Danke
Hänsel

Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 08.11.15 19:39 
So sollte es gehen (ungetestet):

ausblenden Delphi-Quelltext
1:
2:
3:
Datamodule3.ADOQuery_OMDE.close;
Datamodule3.ADOQuery_OMDE.SQL.Text:='Select * From OBJ where Abl_Tag >= ' + QuotedStr(DateToStr(en)) + ' and Abl_Tag <= ' + QuotedStr(DateToStr(bn));
Datamodule3.ADOQuery_OMDE.open;


Falls between auch mit Datum funktioniert (meines Wissens tut es das nur mit Zahlen), wäre der Aufbau ähnlich. Wichtig ist dabei, daß du das Datum in einen String umwandelst und diesen quotest.
Holgerx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 62
Erhaltene Danke: 27

Win95 - Win11 / MSServer2000 - MSServer2019
Delphi 6pro / XE4
BeitragVerfasst: So 08.11.15 20:24 
Hallo..

Da lauern noch Fallstricke...


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
  ADOQuery_OMDE.Close;
  ADOQuery_OMDE.Prepared := true;
  ADOQuery_OMDE.SQL.Text := 'Select * From OBJ where Abl_Tag >= :DateFrom and Abl_Tag < :DateTo';

  ADOQuery_OMDE.Parameters.ParamByName('DateFrom').Value := DayOf(DateTimePicker1.DateTime);
  ADOQuery_OMDE.Parameters.ParamByName('DateTo').Value := IncDay(DayOf(DateTimePicker1.DateTime),1);

  ADOQuery_OMDE.Open;


1.) Kein Datum als String in den Query, denn je nach Datenbanks-Server Sprache/Typ wird der String anders und gegebenenfalls falsch interpretiert.
Deshalb hier am besten mit Parameter arbeiten, dann wird das (Delphi) Datum im korrekten Datumsformat für den Datenbankserver konvertiert.

2.) Da ein Date (ohne Zeitangabe) immer mit 0:00 Uhr währe, würde <= Date immer nur die Datensätze VOR dem Datum liefern, und nicht vom selben Tage auch.
Somit einfach dem Enddatum einen Tag aufadieren und nur mit < arbeiten, dann erhälst Du auch alle Datensätze vom eigendlichen EndDatum.
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 09.11.15 01:56 
DayOf liefert einen Wert von 1 bis 31 zurück. Damit kannst du kein Datum repräsentieren. Vermutlich meintest du stattessen DateOf, das den Datumsanteil eines DateTime-Wertes zurückliefert.

Zudem ist es vollkommen unerheblich, welchen Zeitanteil der gespeicherte Datumswert beinhaltet, wenn sowieso nur das Datum verglichen werden soll. Worin jetzt der Unterschied zwischen DateOf(DateTimePicker1.DateTime) und DateTimePicker1.Date liegen soll, kannst du mir sicher genauer erklären.

Also wenn schon Korinthenhacken, dann richtig :mrgreen:

@Hänsel: Um welches DMBS handelt es sich in deinem Fall?
Holgerx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 62
Erhaltene Danke: 27

Win95 - Win11 / MSServer2000 - MSServer2019
Delphi 6pro / XE4
BeitragVerfasst: Mo 09.11.15 06:40 
Ja, hab mich mit DayOf statt (richtig) DateOf vertippt. ;)

Leider liefert DateTimePicker1.Date bei Delphi6 z.B. immer noch den gesamten DateTime, sprich mit Uhrzeit, nur als TDate gecastet, ohne den Zeitwert ab zu schneiden.
Deshalb habe ich mir angewöhnt, wenn nur das Datum benötigt wird (mit 00:00:00 als Uhrzeit) immer mit DateOf(DateTimePicker1.DateTime) zu arbeiten und so auch nur das Datum zu erhalten.
Sonst erhalte ich noch eine undefinierte Uhrzeit mit am Datum. Dieser Zeitanteil ist bei einem DateTimePicker zumeißt (wenn nicht andersweitig von Hand gesetzt) immer die Uhrzeit vom Erstellungszeitpunkt des Pickers.
(Gerade noch mal getestet)
Somit würde bei bei einer Datenbank mit z.B. >= 16.11.2015 05:20:30 verglichen werden und man somit alle Datensätze zwischen 00:00:00 und 05:20:30 nicht erhalten.


Zum Thema '< Date+1':

Wenn man z.B. bei einem MS-SQLServer >= 16.11.2015 und <= 16.11.2015 angibt, bekommt man ... nichts zurück, auch wenn man diverse Einträge mit 16.11. hat.

Denn der SQL-Server würde bei Datenfeldtyp SMALDATETIME oder DATETIME die Datumsangaben für den Vergleich um 00:00:00 Uhr ergänzen.

Somit Vergleicht er >= 16.11.2015 00:00:00 und <= 16.11.2015 00:00:00.....

Deshalb ist hier >= 16.11.2015 und < 17.11.2015 (>= 16.11.2015 00:00:00 und < 17.11.2015 00:00:00)notwendig, damit auch alle Datensätze vom 16.11.2015 geliefert werden.

Wenn Dies natürlich nicht benötigt wird, sondern nur die Datensätze zwischen den Tagen, ohne die Tage selber, dann müsste es wieder anders lauten.

(Dies ist nur das Beispiel für MS-SQLServer, wie andere Datenbankssysteme einen solchen Vergleich handhaben kann davon abweichen)