2012-02-22 15 views
7

Mam następujące w moim klauzuli where gdzie. Działa na bazie danych Oracle. Pole sc_dt jest zdefiniowane w db jako polu daty.Problemy z TO_DATE

sc_dt = TO_DATE('2011-11-03 00:00:00.0', 'YYYY-MM-DD') 

produkuje następujący błąd "date format picture ends before converting entire input string"

Kiedy próbuję konto dla ułamków sekund (.0 w tym przypadku) z następującymi, pojawia się następujący błąd.

sc_dt = TO_DATE('2011-11-03 00:00:00.0', 'YYYY-MM-DD HH24:MI:SS.FF') 

produkuje następujący błąd "date format not recognized"

Jestem naprawdę tylko przy założeniu, że muszę .FF aby uwzględnić .0 w polu „Od” string. Próbowałem też .FF1, .FF2, ..., .FF9 z tymi samymi wynikami (w tym momencie chwytam się słomek).

O ile widzę, pole sc_dt ma zawsze wypełnioną część miesiąc/dzień/rok (a nie porcję godzina/minuta/sekunda).

Mam debugowanie programu java, który wykonuje powyższy SQL jako przygotowana instrukcja z wartością 2011-11-03 00:00:00.0.

Jak mogę to obejść?

Odpowiedz

6

Musisz użyć opcji sekund po północy. Coś jak:

select TO_DATE('2011-11-03 00:00:01.1', 'YYYY-MM-DD HH24:MI:SS.SSSSS') from dual 

albo to:

select TO_TIMESTAMP('2011-11-03 00:00:00.1', 'YYYY-MM-DD HH24:MI:SS.FF') from dual 
+1

Ty, miły panie, rock. Powinienem był zadać to pytanie GODZINY temu! (akceptuję to jako odpowiedź, gdy tylko przepełnienie stosu pozwoli mi). Dziękuję Ci bardzo! – acedanger

+0

Na pewno moja przyjemność! – northpole

+0

'.FF' nie działa dla mnie. '.SSSSS' zrobił lewę. – acedanger

0

src_dt = select TO_DATE('2011-11-03 00:00:01.1', 'YYYY-MM-DD HH24:MI:SS.SSSSS') from dual

Chyba powyższy jeden powinien działać jeśli wystarczy wyjście daty.

+2

toll TO_DATE będzie działać tylko wtedy, gdy część łańcucha, który identyfikuje ułamków sekund dzieje się również liczba sekund od północy (co może się zdarzyć tylko 9 razy na godzinę). Jeśli twoje godziny są zawsze o północy, nie musi to być problemem. Ale generalnie otrzymasz ORA-01838: sekundy minut konfliktów z sekundami w błędach dziennych. –

5

wyrocznią DATE kolumna jak sc_dt zawsze będą mieć dzień i składnik raz w dół do drugiego. W zależności od narzędzia do wysyłania zapytań i sposobu jego konfiguracji (zwykle jest to sesja NLS_DATE_FORMAT), możliwe jest, że komponent czasu nie jest domyślnie wyświetlany. Można jednak znaleźć komponent czasu wykonując wyraźne TO_CHAR

SELECT to_char(sc_dt, 'YYYY-MM-DD HH24:MI:SS') 
    FROM table_name 

Ponieważ DATE tylko przechowuje czas do drugiej jednak nie można używać ułamków sekund w masce formatu. Więc musisz zrobić coś takiego, aby wyodrębnić tylko część ciągu do ułamków sekund. Jeśli nie masz gwarancji, że ciąg znaków będzie zawsze miał 19 znaków przed przecinkiem dziesiętnym, możesz również użyć parametru INSTR, aby wyszukać kropkę dziesiętną i wziąć wszystko wcześniej.

TO_DATE(substr('2011-11-03 00:00:00.0', 1, 19), 'YYYY-MM-DD HH24:MI:SS') 

Ponieważ pochodzi to z aplikacji Java, lepiej skorzystać z prawidłowego typu danych. Jeśli wiążisz datę Java (java.sql.Date) przy użyciu metody setDate na przygotowanym wyciągu zamiast wiązania łańcucha, to nie będziesz musiał zajmować się formatem ciągu w instrukcji SQL.

+2

Ja lubię rozwiązanie Justina z 'SUBSTR' lepszym niż inne używające modelu formatu' .SSSSS', zarówno z powodów, które podaje w swoich komentarzach na temat innych odpowiedzi, jak i dlatego, że jest bardziej zrozumiałe, że ułamkowa druga składowa czasu jest odrzucany. –

+0

@Justin - Dziękujemy za wyjaśnienie! Pomaga mi zrozumieć, dlaczego robię to, co robię. – acedanger

+0

@Justin: Jednym z powodów, dla których nie należy używać setDate, jest niejawna konwersja strefy czasowej, która występuje między Javą a bazą danych. –

3

Zdaję sobie sprawę, że ten wątek ma więcej niż rok, ale ... Inną opcją prostu wyrzucić go może być:

src_dt=select TO_DATE('2011-11-03 00:00:01.1234', 'YYYY-MM-DD HH24:MI:SS.?????') from dual; 

Uwaga: istnieje dodatkowy „?” wrzucone w celu zilustrowania, że ​​można nawet włożyć kilka dodatkowych "?". Firma Oracle nie składa żadnych skarg, jeśli cyfry reprezentowane przez znaki "?" NIE mają żadnego odpowiedniego znaku w ciągu czasu źródłowego. Może to być pomocne, jeśli nie masz pewności co do dokładności sekund, które otrzymujesz.

Ta opcja daje pewną elastyczność formatowi "ułamków sekund" od czasu źródłowego. Nie wiem, czy jest to faktycznie udokumentowane w dowolnym miejscu.

+1

Ze wszystkich rozwiązań ten działa tylko dla mnie. –

1

Zrobiłem to:

ALTER SESSION 
SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS.?'; 


--Change the decimal 
ALTER SESSION 
SET NLS_NUMERIC_CHARACTERS = ',.'; 

I pracował dla mnie