AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi '24:00' Uhr als Parameter an Query übergeben
Thema durchsuchen
Ansicht
Themen-Optionen

'24:00' Uhr als Parameter an Query übergeben

Ein Thema von MatthiasR · begonnen am 8. Okt 2010 · letzter Beitrag vom 8. Okt 2010
Antwort Antwort
MatthiasR

Registriert seit: 21. Apr 2005
193 Beiträge
 
#1

'24:00' Uhr als Parameter an Query übergeben

  Alt 8. Okt 2010, 08:29
Datenbank: PostgreSQL • Version: 8,.4 • Zugriff über: UniDAC
Wir verwenden die UniDAC-Komponenten, um auf eine PostgreSQL-Datenbank zuzugreifen. In der Datenbank existieren verschiedene Tabellen, in die Uhrzeiten eingetragen werden (Datentyp: time without time zone). Es handelt sich immer um Anfangs- und Endzeiten, wobei die Endzeiten auch den Wert '24:00' Uhr annehmen können. PostgreSQL unterscheidet 0 Uhr und 24 Uhr voneinander, ich weiß nicht, wie es sich da bei anderen DBMS verhält. Bei Delphi gehört 24 Uhr ja quasi schon zum nächsten Tag, da der Nachkommawert eines TDateTime dann wieder voll ist. Daher kann 24 Uhr auch nicht als TDateTime-Parameter übergeben werden.

Aus diesem Grund übergeben wir time-Werte bei Abfragen immer als string-Parameter an die Query und casten den string innerhalb des SQL-Statement auf einen time-Wert. Also z.B. in der Form:

Code:
SELECT * FROM tabelle WHERE uhrzeit BETWEEN cast(:anfang AS time) AND cast(:ende AS time)
Die Parameter belegen wir dann folgendermaßen:

Code:
Query.ParamByName('anfang').AsString := '18:00';
Query.ParamByName('ende').AsString := '24:00';
Sobald die Query jedoch geöffnet wird, wird ein EConvertError ausgelöst der besagt:

"Hour is out of range."

Was ich mich an der Stelle frage, ist, an was die Query hier festmacht, dass der übergebene Parameter einen Zeittyp darstellt, ich übergebe ihn ja explizit als string. Ich hab auch schon versucht, den FieldType der Parameter hart auf ftString zu setzen, hat aber nichts gebracht.

Was ich halt auch nicht weiß, ob das eine "Spezialität" der UniDAC-Komponenten ist, oder ob das Verhalten von einer Delphi-Basisklasse wie dem TDataSet geerbt wurde und sich somit alle Query so verhalten.

Wie kann ich das Beheben, ohne auf die Verwendung von Parametern verzichten zu müssen? Wenn ich die "24:00" hart in das SQL-Statement reinschreibe, dann klappt der Aufruf nämlich.

Geändert von MatthiasR ( 8. Okt 2010 um 08:32 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von mirage228
mirage228

Registriert seit: 23. Mär 2003
Ort: Münster
3.750 Beiträge
 
Delphi 2010 Professional
 
#2

AW: '24:00' Uhr als Parameter an Query übergeben

  Alt 8. Okt 2010, 08:35
Landet auch 24:00 in der Datenbank? Bei MySQL war es so, dass 24:00 Uhr eigentlich 00:00 Uhr ist und der Zeit-Datentyp demzufolge nur von 0:00 - 23:59:59 geht ... Geht es wenn Du aus "24:00" eine "0:00" machst? Kannst Du nicht die Delphi-Referenz durchsuchenStrToTime-Funktion von Delphi verwenden, um die Zeit auch wirklich als Zeit-Wert zu erhalten?
Also ich frage mich gerade nur, wie das dann intern auseinandergehalten werden soll von PostgreSQL...

Viele Grüße
David F.

May the source be with you, stranger.
PHP Inspection Unit (Delphi-Unit zum Analysieren von PHP Code)

Geändert von mirage228 ( 8. Okt 2010 um 08:41 Uhr)
  Mit Zitat antworten Zitat
MatthiasR

Registriert seit: 21. Apr 2005
193 Beiträge
 
#3

AW: '24:00' Uhr als Parameter an Query übergeben

  Alt 8. Okt 2010, 08:48
Also wie das intern auseinander gehalten wird von Postgres weiß ich leider nicht, aber Fakt ist, es geht! Wenn in der Tabelle ein Zeitraum abgespeichert wird, der von 18 - 24 Uhr geht, dann steht auch 24 Uhr in der Tabelle! Wenn Postgres daraus 0 Uhr machen würde, dann wäre das beispielsweise für meine genannte Abfrage fatal:
Code:
select cast('19:00' as time) between cast('18:00' as time) and cast('24:00' as time)
liefert bei Postgres nämlich "True" zurück...
Code:
select cast('19:00' as time) between cast('18:00' as time) and cast('00:00' as time)
logischerweise "False", da der Zeitraum von 0 - 18 Uhr betrachtet wird.

StrToTime bringt mir da leider überhaupt nichts, weil die Funktion sicherlich denselben EConvertError erzeugen dürfte, sollte man ihr "24:00" übergeben.
  Mit Zitat antworten Zitat
Benutzerbild von mirage228
mirage228

Registriert seit: 23. Mär 2003
Ort: Münster
3.750 Beiträge
 
Delphi 2010 Professional
 
#4

AW: '24:00' Uhr als Parameter an Query übergeben

  Alt 8. Okt 2010, 08:55
Hm, Versuch das ganze mal als Integer zu übergeben. Also
Delphi-Quellcode:
.AsInteger := 180000;
.AsInteger := 240000;
Kann Postgre laut Doku auch mit umgehen
David F.

May the source be with you, stranger.
PHP Inspection Unit (Delphi-Unit zum Analysieren von PHP Code)
  Mit Zitat antworten Zitat
MatthiasR

Registriert seit: 21. Apr 2005
193 Beiträge
 
#5

AW: '24:00' Uhr als Parameter an Query übergeben

  Alt 8. Okt 2010, 09:26
Muss ich leider verneinen...
Code:
FEHLER: kann Typ integer nicht in Typ time without time zone umwandeln
LINE 1: select cast('19:00' as time) between cast(180000 as time) an...
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: '24:00' Uhr als Parameter an Query übergeben

  Alt 8. Okt 2010, 09:36
Code:
SELECT * FROM tabelle WHERE uhrzeit BETWEEN cast(:anfang AS time) AND cast(:ende AS time)
Was ich mich an der Stelle frage, ist, an was die Query hier festmacht, dass der übergebene Parameter einen Zeittyp darstellt, ich übergebe ihn ja explizit als string. Ich hab auch schon versucht, den FieldType der Parameter hart auf ftString zu setzen, hat aber nichts gebracht.
Code:
cast(:ende AS time)
Das legt fest, dass der Parameter als Time interpretiert werden soll (muss).

Wenn du abfragen möchtest, was in der Zeit von 18-0 Uhr gewesen ist und es bei anderen Abfragen keine Überschneidungen geben soll, dann müsste die Abfrage ja eigentlich lauten
Code:
00:00 <= Zeit < 09:00
09:00 <= Zeit < 18:00
18:00<= Zeit < 24:00
BETWEEN fragt aber so ab
Code:
00:00 <= Zeit <= 09:00
09:00 <= Zeit <= 18:00
18:00<= Zeit <= 24:00
Somit würden alle Einträge auf den Zeitgrenzen in den Abfragen quasi doppelt erscheinen.
Besser (und damit stressfreier) wäre es mit BETWEEN die Stunde abzufragen
Code:
0 <= Stunde( Zeit ) <= 8
9 <= Stunde( Zeit ) <= 17
18 <= Stunde( Zeit ) <= 23
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von mirage228
mirage228

Registriert seit: 23. Mär 2003
Ort: Münster
3.750 Beiträge
 
Delphi 2010 Professional
 
#7

AW: '24:00' Uhr als Parameter an Query übergeben

  Alt 8. Okt 2010, 09:56
Muss ich leider verneinen...
Code:
FEHLER: kann Typ integer nicht in Typ time without time zone umwandeln
LINE 1: select cast('19:00' as time) between cast(180000 as time) an...
Was ist wenn Du den Typecast nach "TIME" weglässt und nur die Zahl übergibst sodass die Umwandlung implizit erfolgt?
David F.

May the source be with you, stranger.
PHP Inspection Unit (Delphi-Unit zum Analysieren von PHP Code)
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.270 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: '24:00' Uhr als Parameter an Query übergeben

  Alt 8. Okt 2010, 10:55
Hall,

versuche mal today

siehe auch



8.5.1.5
Heiko

Geändert von hoika ( 8. Okt 2010 um 11:01 Uhr)
  Mit Zitat antworten Zitat
MatthiasR

Registriert seit: 21. Apr 2005
193 Beiträge
 
#9

AW: '24:00' Uhr als Parameter an Query übergeben

  Alt 8. Okt 2010, 11:24
Code:
cast(:ende AS time)
Das legt fest, dass der Parameter als Time interpretiert werden soll (muss).
War mir an der Stelle nicht bewusst, aber damit scheinst du Recht zu haben und das hat mich wiederum auf einen Lösungsansatz gebracht, der wohl funktioniert. Statt "cast(:ende as time)" schreibe ich im SQL-Statement einfach "cast(cast(:ende as text) as time)" und der Fisch ist geputzt. "24:00" wird nun zuerst mal als String interpretiert und daher auch angenommen, und anschließend erst von Postgres in einen time-Wert umgewandelt.
Wenn du abfragen möchtest, was in der Zeit von 18-0 Uhr gewesen ist und es bei anderen Abfragen keine Überschneidungen geben soll, dann müsste die Abfrage ja eigentlich lauten
Code:
00:00 <= Zeit < 09:00
09:00 <= Zeit < 18:00
18:00<= Zeit < 24:00
BETWEEN fragt aber so ab
Code:
00:00 <= Zeit <= 09:00
09:00 <= Zeit <= 18:00
18:00<= Zeit <= 24:00
Somit würden alle Einträge auf den Zeitgrenzen in den Abfragen quasi doppelt erscheinen.
Besser (und damit stressfreier) wäre es mit BETWEEN die Stunde abzufragen
Code:
0 <= Stunde( Zeit ) <= 8
9 <= Stunde( Zeit ) <= 17
18 <= Stunde( Zeit ) <= 23
Der "between"-Aufruf sollte lediglich ein Beispiel sein an der Stelle und wird in der Form nicht in meiner Anwendung verwendet. Drum brauchst du da nicht weiter drüber nachzudenken. Aber mir ist die Tatsache bewusst, dass "between" sowohl den Anfangs-, als auch den Endzeitpunkt als zum Zeitraum zugehörig ansieht.
Was ist wenn Du den Typecast nach "TIME" weglässt und nur die Zahl übergibst sodass die Umwandlung implizit erfolgt?
Das hätte ich als nächstes ausprobiert, wobei ich dann eher "24:00" als Parameter übergeben würde, als "240000". Bei "between" könnte das noch funktionieren, bei der von mir ebenfalls verwendeten "overlaps"-Funktion von Postgres aber sicher nicht, die erwartet nämlich eindeutige time-Werte und im Falle des Falles einen expliziten Typcast.
versuche mal today
Denke ich nicht, dass das klappt, da "today" laut der von dir angegebenen Tabelle nur an die Typen "date, timestamp" zugewiesen werden kann, nicht jedoch time.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:34 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