Oracle
 sql >> база данни >  >> RDS >> Oracle

TO_DATE yy,yyyy ми дава различни резултати

Тъй като извършвате ненужно явно преобразуване от низ към дата, което прави имплицитно преобразуване от дата в низ въз основа на вашите NLS настройки.

Това, което трябва да направите, е просто:

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

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

Тъй като sysdate-7 вече е дата, не трябва да извиквате to_date() около това, с всякакъв формат. Като to_date() функцията приема аргумент от низ, вашата sysdate-7 изразът трябва първо да бъде неявно преобразуван в низ. Така че вие ​​наистина правите:

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

който използва вашата NLS_DATE_FORMAT стойност за неявния вътрешен to_char() повикване, така че ако това е кажете 'DD-MON-RR' вие всъщност правите:

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

За да видите какво се случва там, трябва да видите каква е пълната генерирана дата, така че за това ще променя NLS_DATE_FORMAT за сесията, за да показва цялата година:

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

Забележете различните години в последните две стойности. Документацията има раздел за съвпадение на модел на формат . Низът, който имплицитно създавате в средата, има 2-цифрена година. Когато конвертирате низа '30-APR-17' обратно към дата с помощта на YY модел, той „услужливо“ приема текущия век, така че датата завършва като 2017 г. Но когато конвертирате същия низ с помощта на YYYY model смята, че наистина сте имали предвид стойността, която сте предали, и така не приема век - и сте го преминали 17, така че завършвате с година 17; тоест 0017, а не 2017. (Също така бихте получили отговора, който очаквахте, като използвате RRRR , но е много по-добре да се придържате към YYYY и всъщност използват 4-цифрени години навсякъде - ако всъщност изобщо трябва да използвате низ.)

По същество:не разчитайте на настройките на NLS или имплицитни преобразувания на дати в низове или обратно.

В този случай нямате нужда от никакви реализации, така че използвайте по-простото изявление в началото на този отговор.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Изразът е от грешен тип при извикване на функция чрез cx_Oracle

  2. Грешка в callablestatement:липсва IN или OUT параметър при индекс::1

  3. Защо не мога да се свържа чрез jdbc с помощта на SQLcl

  4. oracle PL/SQL как да изчислим обхвата ip за IPv6 cidr

  5. Показване на всички екземпляри, които трябва да бъдат динамично регистрирани със слушател