sql >> Database >  >> RDS >> Oracle

TO_DATE yy,yyyy geeft me verschillende resultaten

Omdat je een onnodige expliciete conversie van string naar datum doet, wat een impliciete . is conversie van datum naar tekenreeks op basis van uw NLS-instellingen.

Wat je zou moeten doen is gewoon:

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

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

Omdat sysdate-7 is al een afspraakje, je zou to_date() niet moeten aanroepen daaromheen, met elk formaat. Als de to_date() functie heeft een stringargument nodig, uw sysdate-7 expressie moet eerst impliciet worden geconverteerd naar een tekenreeks. Dus je doet echt:

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

die uw NLS_DATE_FORMAT-waarde gebruikt voor de impliciete innerlijke to_char() bel, dus als dat is zeg 'DD-MON-RR' je doet eigenlijk:

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

Om te zien wat daar aan de hand is, moet je zien wat de volledige gegenereerde datum is, dus daarvoor ga ik de NLS_DATE_FORMAT voor de sessie wijzigen om het volledige jaar te tonen:

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

Let op de verschillende jaren in de laatste twee waarden. De documentatie bevat een sectie over het matchen van indelingsmodellen . De tekenreeks die u impliciet in het midden maakt, heeft een jaartal van twee cijfers. Wanneer u de tekenreeks '30-APR-17' . converteert terug naar een datum met een YY model, gaat het 'handig' uit van de huidige eeuw, dus de datum eindigt als 2017. Maar als je dezelfde string converteert met een YYYY model denkt het dat je de waarde die je hebt doorgegeven echt meende en gaat er dus niet uit van een eeuw - en je passeerde het 17, dus je eindigt met het jaar 17; dat wil zeggen, 0017 en niet 2017. (U zou ook het antwoord hebben gekregen dat u verwachtte met RRRR , maar het is veel beter om vast te houden aan YYYY en eigenlijk overal 4-cijferige jaren gebruiken - if je moet eigenlijk helemaal een string gebruiken.)

In wezen:vertrouw niet op NLS-instellingen of impliciete conversies van datums naar strings of omgekeerd.

In dit geval heeft u geen . nodig conversies, dus gebruik de eenvoudigere verklaring bovenaan dit antwoord.



  1. Verschil tussen geclusterde en niet-geclusterde index

  2. VBS en het register gebruiken om te bepalen welke versie en 32 versus 64 bit oracle-stuurprogramma's zijn geïnstalleerd

  3. mysql triggers simulatie van beweringen

  4. Meerdere trefwoorden zoeken