Forse circa una settimana fa avevo messo sul mio blog un
piccolo post dove dicevo che non è possibile trasferire in modo "nativo" un
campo Data/Ora di Access ad un campo datetime di SQL
Server 2005. Con nativo intendo che un semplice task di DataFlow non è
sufficiente, perchè l'engine ci ritorna un messaggio:
Error 1 Validation error. Data Flow Task: SQL
Server Destination [34]: The column "DataServizio" can't be inserted because the
conversion between types DT_DATE and DT_DBTIMESTAMP is not supported.
La soluzione c'è, ovviamente, e per tirare le fila del discorso ho deciso di
scrivere un secondo ed ultimo post per chiarire. Già nel mio primo post facevo
riferimento, tra le altre cose, anche ad una pagina tratta dai forum su MSDN,
che riportava una sorta di tabella di conversione tra i data-types di
Integration Services ed i data-types managed. Per fare quello che abbiamo in
testa (ovvero quello di cui si parla nell'oggetto di questo post), non dobbiamo
fare altro che seguire alla lettera questa tabella. Quindi, morale della favola:
prendiamo il campo Data/Ora di Access (che viene visto come
DT_DATE), lo convertiamo in DT_DBTIMESTAMP ed a questo punto
possiamo trasferirlo nel campo destinazione datetime del nostro
db sotto SQL Server 2005.
Vi state chiedendo come, vero? Beh, è più semplice
di quanto possiate immaginare.
Nel nostro progetto che, non dimentichiamocelo, viene realizzato con Visual
Studio 2005, abbiamo per semplicità un solo Data Flow Task
(abbiamo una sola tabella da trasferire), il cui schema interno è definito come
segue:
In breve, abbiamo un OLE DB Source (db in Access) ed un
SQL Server Destination (il db in SQL Server 2005). Notate
l'icona Critical nel riquadro relativo alla destination: difatti, nella
mia task-list appare proprio il messaggio di errore riportato sopra.
Per eliminare l'errore e far funzionare correttamente le cose, dobbiamo
inserire tra source e destination un altro task, denominato Data
Conversion che, come dice il nome stesso, converte un data-type di un
campo in un altro data-type (ovviamente compatibile). Nel nostro caso, quindi,
inseriamo questo blocco fino a raggiungere la configurazione corrente:
Il nostro Source passa prima per una Data
Conversion, la quale entra infine nel blocco
Destination. Voglio fare una piccolo nota sull'interfaccia: per
"spezzare" i collegamenti (le linee verdi che collegano l'uno con l'altro i
task) dobbiamo cliccarci sopra con il pulsante destro e selezionare
Delete. Avrei preferito che le linee fossero semplicemente
reindirizzabili, senza bisogno di cancellarle, anche perchè la
cancellazione effettivamente non c'è. Però magari sono io che sono pignolo!
Comunque sia, se andiamo in Edit nel blocco Data Conversion
possiamo indicare quali campi vogliamo convertire, e soprattutto come. Nel
nostro caso, selezioniamo il campo DataServizio ed andiamo a
dire che vogliamo convertire il tutto in database timestamp
(DT_DBTIMESTAMP). L'engine crea un campo in più, chiamato per default
Copy of DataServizio che rappresenta a tutti gli effetti il
risultato della nostra conversione.
A questo punto, banalmente, possiamo andare a modificare il blocco
SQL Server Destination nella sezione
Mappings, specificando che il campo di input da usare è
Copy of DataServizio e tutto quanto funziona regolarmente.
Difatti, se riempiamo la nostra tabella sotto Access con qualche record e poi
eseguiamo il progetto DTS creato, vedremo come in un batter d'occhio i records
vengono trasferiti da Access a SQL Server senza alcun problema.
Come dicevo l'altra volta, questi due post sono una estrema semplificazione
di quello che devo fare veramente.
Ho messo on-line uno screenshot (1600x1200, 319KBytes) del
mio progetto DTS reale, completo e funzionante (per adesso! ) per chi vuole dargli un'occhiata.