Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Termine anzeigen (https://www.delphipraxis.net/187367-termine-anzeigen.html)

Walter Landwehr 23. Nov 2015 10:56

Datenbank: Firebird • Version: 2.5.5 • Zugriff über: IBO

Termine anzeigen
 
Hallo,

ich möchte alle Termine ermitteln die zwischen 2 abfragen (DateTime) liegen:

Mein SQL sieht so aus.

Delphi-Quellcode:
select
    count(P.patientennummer) as Anzahl
from events E
   inner join tbl_patient P on (E.patientennummer = P.patientennummer)
where
   (P.patientennummer = :Patientennummer)
   and
  (E.startzeit > :Date)
  and
  (E.FINISH <= :ENDDATUM)
Der Delphi Code sieht so aus:
Delphi-Quellcode:
    Termineqry.Close;
    Termineqry.ParamByName('Patientennummer').AsInteger := Patient1Qry.FieldByName('Patientennummer').AsInteger;
    Termineqry.ParamByName('Date').AsDateTime := Now;
    Termineqry.ParamByName('ENDDATUM').AsDate := (now + dmMain.ibqryOptionen.FieldByName('TERMINTAGE').AsInteger);
    Termineqry.Open;
Als Ergebnis werden leider auch Termine angezeigt die vor der Uhrzeit liegen.

Beispiel: Date := 23.11.201511:30:00

Angezeigt wird auch ein Termin der am 23.11.2015 um 8:00 Uhr ist. Das will ich nicht. Wie ist denn die Abfrage korrekt?

mkinzler 23. Nov 2015 11:03

AW: Termine anzeigen
 
Was für ein Typ hat startzeit?

Walter Landwehr 23. Nov 2015 11:06

AW: Termine anzeigen
 
Timestamp

Lemmy 23. Nov 2015 11:23

AW: Termine anzeigen
 
Hallo,

ist das wirklich die Originalabfrage oder hast Du diese fürs Posten noch vereinfacht?

Grüße

Walter Landwehr 23. Nov 2015 11:29

AW: Termine anzeigen
 
Ist so Original.

mkinzler 23. Nov 2015 11:32

AW: Termine anzeigen
 
Versuch mal

Delphi-Quellcode:
Termineqry.ParamByName('Date').Value := Now;

hstreicher 23. Nov 2015 11:35

AW: Termine anzeigen
 
Date ist in Firebird ein "Reserved Word"

http://www.firebirdsql.org/refdocs/l...-reswords.html

ich würde es mal umbenennen

mfg Hannes

Lemmy 23. Nov 2015 11:35

AW: Termine anzeigen
 
OK, dann irritiert mich etwas der Join auf Patienten, den würde ich als erstes entfernen, weil unnötig.

was mir eben auffällt: kannst Du mal den Parameter ":Date" in ":Startdatum" ändern?

Grüße

Walter Landwehr 23. Nov 2015 11:37

AW: Termine anzeigen
 
Nein geht auch nicht. Ergebnis ist das gleiche.

Walter Landwehr 23. Nov 2015 11:39

AW: Termine anzeigen
 
Hallo Lemmy,
der Join auf die Patiententabelle ist nicht überflüssig, da ich nur alle Termine eines bestimmten Patienten haben will.

DeddyH 23. Nov 2015 11:41

AW: Termine anzeigen
 
Zitat:

Zitat von hstreicher (Beitrag 1322213)
Date ist in Firebird ein "Reserved Word"

http://www.firebirdsql.org/refdocs/l...-reswords.html

ich würde es mal umbenennen

mfg Hannes

Wenn ich das richtig gesehen habe, heißt nur der Parameter Date, das sollte also keine Rolle spielen.

Lemmy 23. Nov 2015 11:45

AW: Termine anzeigen
 
Zitat:

Zitat von Walter Landwehr (Beitrag 1322216)
Hallo Lemmy,
der Join auf die Patiententabelle ist nicht überflüssig, da ich nur alle Termine eines bestimmten Patienten haben will.

ja dann mach:

Delphi-Quellcode:
select
    count(patientennummer) as Anzahl
from events E

where
   (patientennummer = :Patientennummer)
   and
  (E.startzeit > :Date)
  and
  (E.FINISH <= :ENDDATUM)
Patientennummer ist ein Feld das es auch in Events gibt, der "Umweg" über die Patiententabelle ist nicht notwendig.

Wenn das ändern von "Date" keine Wirkung zeigt: Hast Du den SQL auch mal in IBExpert, IBConsole,... eingegeben? Kommt dort der selbe Fehler?

Walter Landwehr 23. Nov 2015 11:47

AW: Termine anzeigen
 
Hallo Lemmy,

Parameter habe ich umbenannt, Ergebnis ist ebenso falsch.

nahpets 23. Nov 2015 11:51

AW: Termine anzeigen
 
Ändere doch bitte mal dieses
Delphi-Quellcode:
Termineqry.ParamByName('ENDDATUM').AsDate
in jenes
Delphi-Quellcode:
Termineqry.ParamByName('ENDDATUM').AsDateTime
.
.AsDate ist nun mal halt nur der Tag und damit gehen hier die Stunden verloren.

Walter Landwehr 23. Nov 2015 11:52

AW: Termine anzeigen
 
Hallo Lemmy,

in IBExpert geht es. Verstehe ich nicht so ganz.

vagtler 23. Nov 2015 12:11

AW: Termine anzeigen
 
Zitat:

Zitat von nahpets (Beitrag 1322220)
Ändere doch bitte mal dieses
Delphi-Quellcode:
Termineqry.ParamByName('ENDDATUM').AsDate
in jenes
Delphi-Quellcode:
Termineqry.ParamByName('ENDDATUM').AsDateTime
.
.AsDate ist nun mal halt nur der Tag und damit gehen hier die Stunden verloren.

Es geht um das Anfangsdatum.

Walter Landwehr 23. Nov 2015 12:20

AW: Termine anzeigen
 
Hallo nahpets,

hab ich alles schon probiert, geht trotzdem nicht. Habe den Verdacht das der Parameter nicht richtig übergeben wird.

Sir Rufo 23. Nov 2015 12:23

AW: Termine anzeigen
 
Der JOIN ist überflüssig!
SQL-Code:
select
    count(E.patientennummer) as Anzahl
where
    (E.patientennummer = :Patientennummer)
  and
    (E.startzeit > :ZeitraumVon)
  and
    (E.FINISH <= :ZeitraumBis)
(Der Mix von englisch und deutsch sollte schon mal vermieden werden, dass führt nur zu Verwirrungen - ent-oder-weder)

mkinzler 23. Nov 2015 12:41

AW: Termine anzeigen
 
Das Feld, welches aggregiert wird befindet sich allerdings in der anderen Tabelle

Walter Landwehr 23. Nov 2015 12:43

AW: Termine anzeigen
 
Hallo Sir Rufo,

hilft mir nicht so richtig weiter. Join habe ich entfernt. Ich benutze hier ein TIBOQuery von Jason (IBObjects) und ich habe den Verdacht das hier der Parameter nicht richtig übergeben wird, in IBExpert funktioniert es ja.

mkinzler 23. Nov 2015 12:48

AW: Termine anzeigen
 
Gibt es bei IBO einen Abfrage-Monitor?

baumina 23. Nov 2015 12:54

AW: Termine anzeigen
 
Was ich nicht so ganz verstehe ist, dass dein select ausschließlich eine Anzahl (Count) liefert, du aber schreibst, dass Termine mit dem falschen Datum angezeigt werden. Ist dein select dann doch eher ein select *?

Walter Landwehr 23. Nov 2015 13:56

AW: Termine anzeigen
 
Hallo Mkinzler,

ja gibt es, den habe ich auch gerade probiert.

Delphi-Quellcode:
select
    count(E.patientennummer) as Anzahl
from events E
where
   (E.patientennummer = 16)
   and
  (E.startzeit > '23.11.2015,11:00:00')
  and
  (E.FINISH <= '23.12.2015,15:00:00')
So geht es. Nehme ich allerdings das Komma zwischen Datum und Uhrzeit weg gibt es ein Conversion error to String.
In Delphi wird aber der Parameter now ohne Komma übergeben. Muss jetzt mal testen wie ich das hinbekomme.

mkinzler 23. Nov 2015 14:16

AW: Termine anzeigen
 
Dann stimmt estwas nicht. Bei FireBird ist eine TimeStamp kein String sondern ein Integer. Zudem sollten die Parameter gesendet werden und nicht die Werte der Parameter.

Sir Rufo 23. Nov 2015 14:23

AW: Termine anzeigen
 
Wie sieht denn das Create-Statement für die events-Tabelle aus? :stupid:

Walter Landwehr 23. Nov 2015 14:34

AW: Termine anzeigen
 
Habe es gelöst. So geht es.
Delphi-Quellcode:
    Termineqry.Close;
    Termineqry.ParamByName('Patientennummer').AsInteger := Patient1Qry.FieldByName('Patientennummer').AsInteger;
    Termineqry.ParamByName('Startdatum').asString := DateTimeToStr(Now);
    Termineqry.ParamByName('ENDDATUM').asString := DateTimeToStr(now + dmMain.ibqryOptionen.FieldByName('TERMINTAGE').AsInteger);
    Termineqry.Open;

mkinzler 23. Nov 2015 14:38

AW: Termine anzeigen
 
Mit unnötigem(n) Umweg(en): TimeStamp -> String -> TimeStamp, wenn Deine Angabe des Typs des Feldes (TimeStamp) stimmt.

nahpets 23. Nov 2015 14:57

AW: Termine anzeigen
 
Zitat:

Zitat von Walter Landwehr (Beitrag 1322235)
Delphi-Quellcode:
select
    count(E.patientennummer) as Anzahl
from events E
where
   (E.patientennummer = 16)
   and
  (E.startzeit > '23.11.2015,11:00:00')
  and
  (E.FINISH <= '23.12.2015,15:00:00')

Dies entspräche in Delphi einer Abfrage in der Form
Delphi-Quellcode:
Termineqry.Close;
    Termineqry.ParamByName('Patientennummer').AsInteger := Patient1Qry.FieldByName('Patientennummer').AsInteger;
    Termineqry.ParamByName('Date').AsString := '23.11.2015 11:00:00';
    Termineqry.ParamByName('ENDDATUM').AsString := '23.12.2015 15:00:00');
    Termineqry.Open;
Für meine Begriffe sind die beiden Abfragen (technisch) nicht miteinander vergleichbar.

Sollte der Datentyp in der DB tatsächlich TimeStamp sein, so muss IBExpert hier also auf irgendeine Weise eine Typkonvertierung machen, deren Ergebnis dem erwarteten entspricht.

Now ist in Delphi vom Typ TDateTime und TDateTime wiederum von Typ Double.
Der ganzzahlige Anteil entspricht der den Tagen seit dem 30.12.1899, der Nachkommaanteil der Zeit nach Mitternacht.

Heute ist der 42331 (23.11.2015).
0.47917 entspricht 11:30 Uhr.
0.333334 entspricht 08:00 Uhr.
0.625 entspricht 15:00 Uhr.
42361 entspricht dem 23.12.2015.

Für vergleichbare Ergebnisse (hoffentlich) ohne Typkonvertierung müsste die Abfrage im IBExpert also lauten:

Delphi-Quellcode:
select
    count(E.patientennummer) as Anzahl
from events E
where
   (E.patientennummer = 16)
   and
  (E.startzeit > 42331.47917)
  and
  (E.FINISH <= 42361.625)
und unter Delphi
Delphi-Quellcode:
Termineqry.Close;
    Termineqry.ParamByName('Patientennummer').AsInteger := 16;
    Termineqry.ParamByName('Date').AsDateTime := 42331.47917;
    Termineqry.ParamByName('ENDDATUM').AsDateTime := 42361.625);
    Termineqry.Open;
Bei diesen beiden Abfragen erwarte ich identische Ergebnisse. Ist dem so?
Andernfalls würde ich den Fehler weniger in der Korrektheit der Abfrage, als in Konvertierungsproblemen bei den Datentypen, erwarten.

Die Umschiffung des Problemes mit mehrfachen Typkonvertierungen halte ich für suboptimal, das mag jetzt im konkreten Fall funktionieren, aber ob das jetzt und für alle Zeiten funktioniert? Auf eine derartige "Krücke" würde ich mich nicht verlassen.


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