Inghippi con le date

venerdì 5 ottobre 2012 alle 05:43 | Pubblicato su Diario | 5 commenti

Cercando di caricare un file CSV con Oracle External Tables sono capitato in un caso in cui la conversione da stringhe a date di Oracle fallisce,

Ho file in cui le date sono inserite nel formato “ddmmyyyy”, però in alcuni casi, almeno i giorni non sono sempre a due cifre, quindi ad esempio ho trovato un caso in cui la data era “2122002″ e Oracle mi dava errore. La cosa è facilmente replicabile anche da SQL:


CRISTIAN@svil112 > select to_date('2122002','ddmmyyyy') from dual;
select to_date('2122002','ddmmyyyy') from dual
 *
ERROR at line 1:
ORA-01843: not a valid month

Si tratta di un problema che ho trovato discusso anche su AskTom, qui esattamente, ma li per li non ho capito la soluzione (la sintassi proposta per la soluzione mi pare errata), ma in sostanza credo che la soluzione volesse essere quella che gia io utilizzavo, cioè:

...
DATA_CREAZIONE char(8) date_format DATE mask 'ddmmyyyy',
...

Ma a me appunto da l’errore sopra indicato. La differenza è che nel mio caso nella stringa di descrizione della data non ci sono separatori fra i numeri che descrivono giorno, mese e anno, infatti:

CRISTIAN@svil112 > select to_date('2-12-2002','dd-mm-yyyy') from dual;

TO_DATE('2-12-2002'
-------------------
02-12-2002 00:00:00

In questo caso evidentemente Oracle è in grado di estrarre correttamente la data dalla stringa

About these ads

5 commenti »

RSS feed dei commenti a questo articolo. TrackBack URI

  1. C’ho perso più di un paio d’ore su questo tuo problema (non perché mi serva, ma solo per diletto e sfida personale) e devo dire che non sono arrivato ad una soluzione soddisfacente.
    Comunque da due tests si capisce facilmente che tutto dipende dal fatto che Oracle interpreta il pattern ‘ddmmyyyy’ della data, partendo da sinistra e quindi per lui la data ’2122002′ corrisponde a ’21/22/002′, che è ovviamente errata nel mese, come da messaggio d’errore.
    Ho perciò cercato in prima battuta qualche formato data disponibile che potesse ovviare alla situazione, ma non ho trovato nulla di utile.
    Poi ho pensato di trasformare in fase di caricamento la colonna, e ho trovato che, mentre con SQL*Loader si sarebbe risolto mettendo nel control file (testato funziona) qualcosa del tipo:
    data_creazione date ‘ddmmyyyy’ “lpad(:data_creazione, 8, ’0′)”
    la sintassi di creazione dell’external table non contempla l’inserimento di funzioni allo stesso modo.

    • La soluzione LPAD è quella che applico a posteriori dopo aver caricato come stringa il campo, però secondo me è concettualmente sbagliato che il campo non sia gia così formato in partenza. Infatti se anche per il mese si fa così non se ne esce ed ho verificato e in passato, nel mio caso specifico il campo era sempre da 8 caratteri.

      • Ciao Cristian,
        potresti ovviare mettendo antecedendo l’anno rispetto al giorno, per intenderci:

        select to_date(’2002122′,’yyyymmdd’) from dual;

        in questo caso funziona correttamente

        Ciao
        Alessandro

  2. Ma usare una length in modo da usare una format date mask differente a seconda dei casi?

    • in realtà non basta, perché se ho la data scritta come ’2122002′ non c’è modo, se non faccio prima l’LPAD, di fargliela capire ad Oracle


Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

Crea un sito o un blog gratuitamente presso WordPress.com. | The Pool Theme.
Entries e commenti feeds.

Iscriviti

Ricevi al tuo indirizzo email tutti i nuovi post del sito.

Unisciti agli altri 70 follower

%d blogger cliccano Mi Piace per questo: