Fehler bei Filterung nach Datum

kwakz

Aktiver Benutzer
Beiträge
29
Hallo zusammen,

ich bin neu auf dem Gebiet der Datenbanken udn hätte schon gleich mal ein Problem. Ich würde gern meine Daten in einer bestimmten Zeitspanne filtern. Ich hätte geglaubt, dass das so funktionieren könnte:

Code:
SELECT *
FROM [2895R].[dbo].[T_Produktion]
WHERE Auflegezeit between '2013-07-20 00:00:00.000' and '2013-22-24 23:59:59'

Leider bekomme ich dabei folgende Fehlermeldung:

Msg 242, Level 16, State 3, Line 2
Bei der Konvertierung eines varchar-Datentyps in einen datetime-Datentyp liegt der Wert auerhalb des gltigen Bereichs.


Kann mir da jemand auf die Spränge helfen?

Mfg Daniel
 
Werbung:

akretschmer

Datenbank-Guru
Beiträge
9.731
Hallo zusammen,

ich bin neu auf dem Gebiet der Datenbanken udn hätte schon gleich mal ein Problem. Ich würde gern meine Daten in einer bestimmten Zeitspanne filtern. Ich hätte geglaubt, dass das so funktionieren könnte:

Code:
SELECT *
FROM [2895R].[dbo].[T_Produktion]
WHERE Auflegezeit between '2013-07-20 00:00:00.000' and '2013-22-24 23:59:59'



Mfg Daniel

Es gibt keinen 22. Monat.
 

akretschmer

Datenbank-Guru
Beiträge
9.731
Hoppla ... ändert aber leider nichts am Problem

Sicher?

Code:
test=*# select '2013-22-24 23:59:59'::timestamp;
ERROR:  date/time field value out of range: "2013-22-24 23:59:59"
LINE 1: select '2013-22-24 23:59:59'::timestamp;
               ^
HINT:  Perhaps you need a different "datestyle" setting.
test=*# select '2013-12-24 23:59:59'::timestamp;
      timestamp
---------------------
 2013-12-24 23:59:59
(1 row)

Andreas
 

akretschmer

Datenbank-Guru
Beiträge
9.731
Leider ja. Ich habe auch schon ein bisschen rumexperimentiert und nach anderen Einträgen gefiltert ... das hat funktioniert. Nur die Geschichte mit dem Zeitstempel will nicht funktionieren.

Selbe Fehlermeldung wie erst?

Code:
test=*# select * from foo;
 id |        zeit
----+---------------------
  1 | 2013-07-20 00:00:00
  2 | 2013-08-20 00:00:00
  3 | 2013-09-20 00:00:00
  4 | 2013-10-20 00:00:00
(4 rows)

test=*# select * from foo where zeit between '2013-07-21 00:00:00.000' and '2013-09-20 23:59:59.000';
 id |        zeit
----+---------------------
  2 | 2013-08-20 00:00:00
  3 | 2013-09-20 00:00:00
(2 rows)
 

Margit

Fleissiger Benutzer
Teammitglied
Beiträge
56
Einfach ein Datum als String in eine Abfrage zu schreiben ist eine ziemlich unzuverlässige Methode.

Warum?
01-05-2013 bedeutet für einen Mitteleuropäer 1. Mai 2013.
01-05-2013 bedeutet für einen Amerikaner 5. Jänner 2013.

Also besser die dafür vorgesehenen Funktionen verwenden, bei Oracle TO_DATE() und bei SqlServer CAST():

Code:
SELECT CAST('01-JAN-2013' AS DATETIME)
 

akretschmer

Datenbank-Guru
Beiträge
9.731
Einfach ein Datum als String in eine Abfrage zu schreiben ist eine ziemlich unzuverlässige Methode.

Warum?
01-05-2013 bedeutet für einen Mitteleuropäer 1. Mai 2013.
01-05-2013 bedeutet für einen Amerikaner 5. Jänner 2013.

Also besser die dafür vorgesehenen Funktionen verwenden, bei Oracle TO_DATE() und bei SqlServer CAST():

Code:
SELECT CAST('01-JAN-2013' AS DATETIME)

Nachtrag noch dazu: Man kann auch steuern, wie ein Datum ausgegeben wird:

Code:
test=# show datestyle;
 DateStyle
-----------
 ISO, DMY
(1 row)

Time: 42,466 ms
test=*# select current_date;
    date
------------
 2013-07-24
(1 row)

Time: 101,125 ms
test=*# set datestyle=sql;
SET
Time: 0,070 ms
test=*# select current_date;
    date
------------
 24/07/2013
(1 row)

Time: 0,150 ms
test=*# set datestyle=german;
SET
Time: 0,064 ms
test=*# select current_date;
    date
------------
 24.07.2013
(1 row)

Andreas
 

ukulele

Datenbank-Guru
Beiträge
4.702
Unabhängig davon ob man den String einfach in den Code schreibt oder explizit konvertiert ist immer die Spracheinstellung in der DB entscheidend. I.d.R. steht die auf Englisch und auch wenn er das Datum in der Ausgabe im deutschen Format ausspuckt muss man es für die Eingabe wieder in englischer Schreibweise bereit stellen.
 

Tommi

Datenbank-Guru
Beiträge
290
Hi,

dann gebe ich jetzt meine bevorzugte Variante mit CONVERT auch noch hinzu. Mit diesem Befehl kann nämlich zusätzlich gesteuert werden, welches Darstellungsformat denn nun angegeben werden soll.
Dazu gibts natürlich auch genauere Infos von Microsoft: http://msdn.microsoft.com/de-de/library/ms187928.aspx

Ein Beispiel für die Anwendung habe ich auch noch:
Code:
DECLARE @vonDatum datetime, @bisDatum datetime
 
SET @vonDatum=CONVERT(datetime, '13.08.2013', 104)
SET @bisDatum = DATEADD(second,  86399, @vonDatum)
 
SELECT *
FROM [2895R].[dbo].[T_Produktion]
WHERE Auflegezeit between @vonDatum AND @bisDatum

Da die Auflegezeit vermutlich als datetime-Datentyp vorliegt und über die Variablen des gleichen Datentyps verglichen wird, muss nur die Konvertierung ins datetime-Format korrekt sein. Dabei ist es dann auch egal welche Spracheinstellung die SQL Server Instanz hat.

Viele Grüße,
Tommi
 

funkyice

Benutzer
Beiträge
21
Dann sollte man in der WHERE-Abfrage aber auch gleich die "Auflegezeit" in einer CONVERT-Funktion verpacken, so dass mit demselben Wert verglichen wird.
 

Benutzer0000

Benutzer
Beiträge
13
Code:
SELECT *
FROM
    [2895R].[dbo].[T_Produktion]
 
WHERE
    Convert(DateTime ,Auflegezeit) between '2013-07-20 00:00:00.000' and '2013-22-24 23:59:59.997'

Da in deiner Datenbank die "Auflegezeit" as Zeichenfolge und nicht als Datum gespeichert ist, musst du diesen vorher auf ein Datum umwandeln.

So müsste es dann aber auch funktionieren ~

MFG
 
Werbung:

ukulele

Datenbank-Guru
Beiträge
4.702
Code:
SELECT *
FROM
    [2895R].[dbo].[T_Produktion]
 
WHERE
    Convert(DateTime ,Auflegezeit) between '2013-07-20 00:00:00.000' and '2013-22-24 23:59:59.997'

Da in deiner Datenbank die "Auflegezeit" as Zeichenfolge und nicht als Datum gespeichert ist, musst du diesen vorher auf ein Datum umwandeln.

So müsste es dann aber auch funktionieren ~

MFG
Und schon knallt es wieder sobald das Ausgabeformat von DATETIME nicht dem Format des Datums in der Zeichenfolge entspricht...
 
Oben