Un’attività molto comune per chi lavora con DB2 for i è trovarsi nella necessità di importare informazioni da fonti dati esterne e immagazzinarle in tabelle del DB2.
Esistono vari metodi e vari contesti in cui si rende necessario acquisire dati da fonti esterne al DB2. In questo articolo focalizziamo l’attenzione sull’importazione di dati partendo da file di testo di tipo CSV.
Un file CSV (Comma-Separated Value) è un file di testo in cui ogni riga rappresenta un record e all’interno di ogni riga i “campi” sono separati tramite un carattere speciale.
Il documento di riferimento che descrive il formato CSV è la RFC 4180 che recita così nella parte introduttiva:
The comma separated values format (CSV) has been used for exchanging and converting data between various spreadsheet programs for quite some time. Surprisingly, while this format is very common, it has never been formally documented […] This RFC documents the format of comma separated values (CSV) files and formally registers the “text/csv” MIME type for CSV in accordance with RFC 2048.
Index
Il carattere con cui vengono delimitati i campi può essere ovviamente la virgola “,”, in accordo con la denominazione stessa del formato, ma possono essere utilizzati altri caratteri. I più comuni sono: tabulazione, punto e virgola “;”, pipe “|”, spazio ” “.
La scelta del carattere separatore di campo è una scelta che si subisce, nel caso in cui si riceva il file da una fonte esterna che non può essere controllata da noi e quindi ci si deve adeguare.
Nel caso in cui si abbia la possibilità di scegliere il carattere separatore personalmente prediligo o il pipe o la tabulazione; ovvero caratteri che molto raramente potranno essere presente nel contenuto dei campi.
Come evidenzia la RFC 4180 NON esiste uno standard riconosciuto per il formato CSV, quindi esiste una varietà di interpretazioni. In ogni caso la RFC 4180 tenta di definire alcune regole per scrivere “bene” un file csv. Sintetizzo le regole principali:
Non viene descritto nella RFC 4180, però nella prima riga di un file csv si può specificare il parametro
sep=<delimiter>
per indicare quale è il carattere separatore dei campi.
Per quanto non ho mai visto un file csv che contenga tale parametro.
Per importare un file CSV in una tabella del DB2 bisogna innanzitutto copiarlo in una cartella nel file system “root” e poi utilizzare il comando CPYFRMIMPF.
Il comando CpyFrmImpF copia un “import file” (nel nostro caso il file CSV) in un file fisico/logico.
In linea generale si definisce “import file” un file creato allo scopo di copiare dati tra sistemi eterogenei.
Analizziamo i parametri più importanti di questo comando utili per importare un file csv in una tabella di DB2.
La tabella deve già esistere nel DB2 e i campi della tabella devono corrispondere con i campi presenti nel file CSV.
Il tipo dati dei campi della tabella del DB2 deve essere compatibile con il contenuto del file CSV.
Ovvero se per esempio il 3º campo della tabella è definito numerico lungo 5 di cui 2 decimali, il contenuto del 3º campo in tutte le righe del file CSV deve essere o nullo oppure contenere un numero valido con al massimo 3 interi e 2 decimali e deve esserci il carattere separatore dei decimali (o la virgola o il punto).
Per ogni errore che il DB2 riscontra cercando di importare il contenuto dei vari campi del file CSV viene registrato un messaggio nel joblog del lavoro e la riga interessata dall’errore viene scartata. Nel messaggio presente nel joblog viene nella maggior parte dei casi specificato esattamente su quale campo è stato riscontrato il problema.
N.B. L’importazione NON si interrompe alla prima riga che presenta un errore, ma prosegue a importare le righe successive.
Analizziamo in dettaglio i parametri più importanti del comando CPYFRMIMPF:
Il comando CpyFrmImpF consente di copiare in un file degli “errori” le righe del file CSV che non sono state importate. E’ una possibilità forse poco conosciuta, ma molto comoda per identificare più facilmente le righe che vengono scartate dall’importazione. Molto utile soprattutto quando il file csv contiene centinaia o migliaia di righe.
I parametri da usare per gestire il file degli errori sono:
CRTSRCPF FILE(QGPL/ERRORI) RCDLEN(550) MBR(*FILE) SIZE(*NOMAX)
Se si hanno dubbi su quale sia il carattere di fine riga di un file csv lo si può aprire e controllare gli ultimi caratteri della riga visualizzandoli in modalità esadecimale.
Aprire il file csv memorizzato in una cartella su IFS con il comando DSPF
oppure usando l’opzione 5=Visualizzazione dal comando WRKLNK
.
Spostare la visualizzazione verso destra fino a mostrare la parte finale della riga: digitare nel posizionamento per colonna l’ultima colonna del file di testo. Quindi premere F10=Visualizzazione esadecimale
Nel caso in cui si debba importare nel DB2 file di testo a colonne fisse, può tornare comunque utile utilizzare il comando CPYFRMIMPF.
In aggiunta a quanto scritto finora è necessario fornire un file di definizione del file da importare ovvero un file FDF (field definition file).
Ogni riga del file FDF contiene le seguenti informazioni:
I 4 valori devono essere separati da uno spazio.
Altre informazioni utili relative al file FDF:
L’indicatore di valore nullo nel file di testo deve avere i valori Y o N.
Esempio file FDF:
-- codice articolo CODART 1 15 0 -- descrizione articolo DESART 16 50 0 -- prezzo di listino PREZZO 51 13 0 *END queste righe dopo *END saranno ignorate
Leggi questo articolo e molti altri sul sito https://www.markonetools.it
Le funzioni di debug con Visual Studio Code sono disponibili da qualche tempo ma questa nuova versione 2.10.0 semplifica la…
A distanza di due anni e mezzo dal mio post Trasferire oggetti con ObjectConnect ed Enterprise Extender, sono finalmente riuscito…
Con un piccolo trucco anche una semplice istruzione SELECT può eseguire qualsiasi comando di sistema ! Vediamo come...
Una mini-guida a puntate per la configurazione, gestione, uso e risoluzione dei problemi di IBM i NetServer
Una mini-guida a puntate per la configurazione, gestione, uso e risoluzione dei problemi di IBM i NetServer
Una mini-guida a puntate per la configurazione, gestione, uso e risoluzione dei problemi di IBM i NetServer
View Comments
Ciao,
ho letto il post e ho sistemato un po' il CLP che legge una cartella IFS e converte i file csv in essa contenuti in un file DB2. Viene elaborato solo il primo file perché, in caso di errori, viene mandata a termine la procedura.
Il primo file contiene 500.000 records dei quali 499.933 vengono accodati e 67 no.
Ho inserito nel comando CPYFRMIMPF la gestione del file errori e vedo che i record non copiati hanno un carattere strano in un campo che ho definito numerico nel mio file DB2.
Di seguito alcuni esempi dei valori non importati:
0,021067R
0,020882L
0,020952L
0,020000è
0,020000è
0,020989è
0,020000è
0,020833L
Il campo sul file DB2 è definito numerico 11,7 ma non capisco quel valore in fondo al campo.
Può indicare un valore negativo??
Ci sono altri campi che hanno regolarmente un - prima dell'importo per cui non so cosa pensare.
C'è un modo per normalizzare questi sporchi?
Forse il file csv ha un cssid diverso?
L'alternativa è definire tutti i campi alfanumerici e poi passare in rassegna tutto il file per convertire quello che va sistemato??
Grazie per ogni suggerimento in merito.
Davide
Deduco che il file csv che sta cercando di importare sia il risultato di un precedente esportazione da una tabella dove alcuni campi numerici sono stati esportati non correttamente (intendo dal punto di vista del tipo dati numerico). Quindi se il campo del file csv che dovrebbe essere interpretato come numerico contiene delle lettere e si cerca di importarlo in un campo numerico di una tabella del DB2 giustamente il record viene scartato.
L'indagine andrebbe eseguita quindi sulla prima fase di esportazione che ha creato il csv e non tanto su quella di importazione che fallisce "giustamente" su quei record che sono formalmente non compatibili con i campi della tabella del DB2. Certamente una possibile soluzione è definire il campo della tabella alfanumerico per fare in modo che il comando CPYFRMIMPF importi tutti i record. Ma si posticipa solo il problema, perché comunque rimangono dei record con numeri non validi in un campo che si desidererebbe trattare come numero.