Oracle
 sql >> Baza danych >  >> RDS >> Oracle

TO_DATE rr,rrrr daje mi różne wyniki

Ponieważ robisz niepotrzebną jawną konwersję z ciągu na datę, co jest niejawnym konwersja z daty na ciąg na podstawie ustawień NLS.

To, co powinieneś zrobić, to po prostu:

select to_char(sysdate - 7, 'year') from dual;

TO_CHAR(SYSDATE-7,'YEAR')                 
------------------------------------------
twenty seventeen

Ponieważ sysdate-7 jest już datą, nie powinieneś wywoływać to_date() wokół tego, w dowolnym formacie. Jako to_date() funkcja przyjmuje argument w postaci łańcucha, twój sysdate-7 wyrażenie musi być najpierw niejawnie przekonwertowane na ciąg. Więc naprawdę robisz:

select to_char(to_date(to_char(sysdate - 7), 'DD/MM/YYYY'), 'year') from dual;

który używa Twojej wartości NLS_DATE_FORMAT dla niejawnej wewnętrznej to_char() zadzwoń, więc jeśli to jest powiedz 'DD-MON-RR' faktycznie robisz:

select to_char(to_date(to_char(sysdate - 7, 'DD-MON-RR'), 'DD/MM/YYYY'), 'year') from dual;

Aby zobaczyć, co się tam dzieje, musisz zobaczyć, jaka jest pełna wygenerowana data, więc w tym celu zmienię NLS_DATE_FORMAT, aby sesja pokazywała cały rok:

alter session set nls_date_format = 'SYYYY-MM-DD';

select sysdate - 7 as raw_date,
  to_char(sysdate - 7, 'DD-MON-RR') as implicit_string,
  to_date(to_char(sysdate - 7, 'DD-MON-RR'), 'DD/MM/YY') as implcit_yy,
  to_date(to_char(sysdate - 7, 'DD-MON-RR'), 'DD/MM/YYYY') as implcit_yyyy
from dual;

RAW_DATE    IMPLICIT_STRING    IMPLCIT_YY  IMPLCIT_YYY
----------- ------------------ ----------- -----------
 2017-04-30 30-APR-17           2017-04-30  0017-04-30

Zwróć uwagę na różne lata w ostatnich dwóch wartościach. Dokumentacja zawiera sekcję dotyczącą dopasowywania modeli formatu . Ciąg, który tworzysz niejawnie w środku, ma 2-cyfrowy rok. Po przekonwertowaniu ciągu '30-APR-17' powrót do daty za pomocą YY model, „pomocnie” zakłada bieżący wiek, więc data kończy się na 2017 r. Ale kiedy przekonwertujesz ten sam ciąg za pomocą YYYY model myśli, że naprawdę miałeś na myśli wartość, którą przekazałeś, więc nie zakłada wieku - i zdałeś go 17, więc otrzymujesz rok 17; to znaczy 0017, a nie 2017. (Otrzymałbyś również oczekiwaną odpowiedź, używając YYYY , ale znacznie lepiej jest trzymać się YYYY i faktycznie wszędzie używamy 4-cyfrowych lat – jeśli faktycznie musisz w ogóle użyć ciągu znaków).

Zasadniczo:nie polegaj na ustawieniach NLS ani niejawnych konwersji dat na ciągi i odwrotnie.

W takim przypadku nie potrzebujesz żadnych konwersji, więc użyj prostszej instrukcji na górze tej odpowiedzi.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dlaczego otrzymuję błąd Oracle podczas wywoływania procedury z C#?

  2. DML i obsługa wyjątków — Oracle

  3. Konwertuj typ danych znacznika czasu na znacznik czasu uniksa Oracle

  4. Konwertowanie dnia roku na datę, gdy niektóre formaty daty mają DDRRRR, a niektóre mają DDDYYYY w Oracle

  5. Aktualizuj wartości PL/SQL przy użyciu DUP_VAL_ON_INDEX