2016-01-12 16 views
15

Ho appena rilevato un comportamento strano della funzione oracle TO_DATE quando utilizzato con il parametro format_mask.Oracle TO_DATE NON errore di lancio

Fondamentalmente, quello che vedo è che in un caso ignora la maschera di formattazione data, e analizza l'input con la propria maschera, e in altri casi genera un'eccezione.

esempio I atteso comportamento - Errore gettato:

SELECT TO_DATE('18-02-2016', 'DD/MON/YYYY') FROM dual 

ORA-01843: non un mese valido

Esempio II ANOMALO - Data analizzata:

SELECT TO_DATE('18-feb-2016', 'DD/MM/YYYY') FROM dual 

18 febbraio 2016 00:00:00

non riesco a vedere alcuna osservazione di questo nel docs, quindi mi chiedo se questo incostincency legato alla progettazione o è bug o forse non sto capire qualcosa corretta?

Modifica: Guardando le risposte, posso essere d'accordo sul fatto che sia molto probabilmente di progettazione. Ma quello che viene fatto qui sembra pericolosamente "automatico" per me.

Cosa succede se il formato verrà interpretato (indovinato da oracle) in modo errato? C'è qualche documentazione su cosa sta succedendo esattamente qui, quindi posso essere sicuro che sia sicuro?

La mia domanda sarebbe: posso spegnere? La mia unica opzione è la convalida del formato da solo?

+0

mi sono preso la libertà di correre i frammenti e la modifica della domanda di includere uscita effettiva. Penso che potrebbe essere rilevante ottenere "ORA-01843: non un mese valido" e non "ORA-01830: l'immagine in formato data termina prima di convertire l'intera stringa di input" o qualcos'altro. –

risposta

18

veda la tabella qui: https://docs.oracle.com/cd/B28359_01/server.111/b28286/sql_elements004.htm#g195479

Fa parte della sezione String-To-Date Regole di conversione del modello in formato datetime. Nel caso di MM se non c'è corrispondenza, tenta MON e MONTH. Allo stesso modo se si specifica MON e non lo trova, tenta MONTH. Se si specifica MONTH e non riesce a trovarlo, tenta MON, ma non tenterà mai di effettuare il MM su qualsiasi numero eccetto MM.

In risposta alla domanda: Can I turn it off? La risposta è sì.

È possibile farlo specificando FX come parte della formattazione.

SELECT TO_DATE('18/february/2016', 'FXDD/MM/YYYY') FROM dual; 

ora ritorna:

[Errore] Execution (4: 16): ORA-01.858: un carattere non numerico è stato trovato dove era previsto un numerica

Mentre il seguente:

SELECT TO_DATE('18/02/2016', 'FXDD/MM/YYYY') FROM dual; 

Restituisce il previsto:

2/18/2016

Si noti che quando si specifica FX si MUST usare i separatori corretti altrimenti errore.

+1

Esattamente quello di cui ho bisogno, grazie. Inoltre, la risposta era nella pagina che ho collegato alla mia domanda. o.O davvero avrei dovuto leggerlo fino alla fine. –

+1

Nessun problema, è una sezione piuttosto piccola alla fine di un documento altrimenti di grandi dimensioni. =) – gmiley

4

Questo è di progettazione. Oracle tenta di trovare la rappresentazione della data deterministica nella stringa anche se non è conforme alla maschera definita. Getta l'errore solo che non trova la data deterministica o che alcuni componenti richiesti della data mancano o non sono risolti.

+0

Che cos'è esattamente questa "rappresentazione deterministica della data" e come funziona? Dove posso trovare una descrizione? E più importante - come posso spegnerlo? Inoltre, se consideri il mio esempio, puoi vedere che in entrambi i casi Oracle ha esattamente le stesse informazioni per riconoscere il formato reale e in entrambi i casi lo fa correttamente. –

+1

Si spegne quando si specifica la maschera esatta: 'FX '. In realtà stavo lavorando con il determinismo perché 'TO_DATE ('2016111', 'YYYYMMDD')' non è deterministico potrei essere 2016-11-01 o 2016-01-11 e Oracle preferisce il primo elemento quindi è 2016-11-01 . – Husqvik

2

Penso che un 02 potrebbe significare data/mese/anno qualsiasi cosa, ma feb significherebbe solo una cosa, un month. Ho anche effettuato il controllo incrociato dello stesso in 11g e ho ottenuto lo stesso risultato ottenuto con 12c. Quindi lo ha il come oracle design.

+0

Sì, ma 'SELECT TO_DATE ('feb-08-2016', 'DD/MM/YYYY') FROM dual' fallisce, giusto? Aggiornerò la mia domanda con per essere più specifici. –

+0

Questo ha dato errore, ma 'SELECT TO_DATE ('feb-08-2016', 'MM/DD/YYYY') DA doppio;' no. Quindi deve essere di progettazione – Utsav

2

Se si desidera disattivare il tentativo di Oracle di essere utile e interpretare le cose che non corrispondono esattamente, è possibile utilizzare the FX format modifier:

FX
formato esatto. Questo modificatore specifica corrispondenza esatta per il formato modello argomentazione carattere e datetime di una funzione TO_DATE:

  • punteggiatura e testo citato nell'argomento carattere devono corrispondere (eccetto per caso) le parti corrispondenti del modello di formato.
  • L'argomento di carattere non può contenere spazi in più. Senza FX, Oracle ignora gli spazi in più.
  • I dati numerici nell'argomento carattere devono avere lo stesso numero di cifre dell'elemento corrispondente nel modello di formato. Senza FX, i numeri nell'argomento carattere possono omettere gli zeri iniziali.
  • Quando FX è abilitato, è possibile disabilitare questo controllo per zeri iniziali usando anche il modificatore FM.

Così il vostro esempio potrebbe errore con:

SELECT TO_DATE('18-feb-2016', 'FXDD/MM/YYYY') FROM dual; 

SQL Error: ORA-01858: a non-numeric character was found where a numeric was expected 

Questo richiederà anche i delimitatori corrispondere esattamente:

SELECT TO_DATE('18-02-2016', 'FXDD/MM/YYYY') FROM dual; 

SQL Error: ORA-01861: literal does not match format string 

Se lo fanno bene allora è OK:

SELECT TO_DATE('18/02/2016', 'FXDD/MM/YYYY') FROM dual; 
SELECT TO_DATE('18-feb-2016', 'FXDD-MON-YYYY') FROM dual; 

Non si lamenta del diverso caso nel secondo esempio. Ma si lamenterà se ometti gli zeri iniziali;

SELECT TO_DATE('18/2/2016', 'FXDD/MM/YYYY') FROM dual; 

SQL Error: ORA-01862: the numeric value does not match the length of the format item 

...a meno che non anche includono il modificatore FM:

SELECT TO_DATE('18/2/2016', 'FMFXDD/MM/YYYY') FROM dual; 
Problemi correlati