Quando utilizziamo lo Script Task ed in generale quando scriviamo codice, è molto importante darsi delle ben precise regole di scrittura, al fine di avere un buon controllo sia a livello di manutenibilità, sia a livello di leggibilità del codice stesso. Visto che con SSIS ora è possibile utilizzare la OOP fornita dal framework, perchè non sfruttarla il più possibile?
Passando da DTS a Integration Services, ognuno di noi può essere portato a considerare il codice scritto come un vero e proprio ActiveX Script della versione di SQL Server 2000..
Ma lo Script task offre molte possibilità in più.. è infatti possibile scrivere classi interne da utilizzare poi in più punti dello script, utilizzare costrutti .net, scrivere insomma "più ad oggetti".
Una mancanza che si sente sulla versione 2005, anche SP2, è quella di C#.. A dire il vero SSIS è un raccordatore di linguaggi
.. Da XML, alla sintassi simil C delle expressions, a VB.Net.. Si potrebbe dire.. "MA PERCHE' ESCLUDERE IL NOSTRO CARO C#??"
Almeno, Katmai risolverà questa annosa questione e fornirà il supporto sia per VB.Net che per C#, leggete
questo link.
A prescindere dal linguaggio, come dicevamo, è molto importante darsi delle regole da seguire..
Nel corso della mia esperienza su SSIS, ho notato come semplici cose possano dare grandi vantaggi. Rischio di essere scontato nel parlare di ciò che segue, ma la mia opinione è che non si deve
mai trascurare nulla.Come esempio prendiamo proprio uno Script Task. Immaginiamo di dover scrivere su un file di testo
n volte un
guid sempre diverso. Il path è salvato in una variabile del package così come l'ID da scrivere ed il numero di volte da iterare la scrittura. Chiameremo rispettivamente le tre variabili FilePath, StringToWrite e Occurrence. FilePath, rimanendo sempre identica, sarà una variabile
ReadOnly a livello di package.
Ed ora, come si potrebbe scrivere il codice che crea il file se non esiste e che scrive sul file
n volte la stringa? In tanti modi di sicuro.. Sì, è vero, gli oggetti utilizzati saranno del tutto simili tra loro, ma quello che potrebbe cambiare è l'organizzazione del codice. Intanto passiamo a configurare lo script
Come possiamo notare, passo in ReadOnly il path del file (per forza di cose, poichè è readonly per il package) e le occorrenze, mentre lascio in lettura/scrittura la StringToWrite, in modo che possa cambiare all'interno dello script. Come muoversi per scrivere il codice? Per quanto mi riguarda, seguo sempre la regola di utilizzare le proprietà, le region ed i metodi, lasciando al metodo principale l'unico compito di richiamare proprio i membri scritti da me. Un esempio può essere il codice sottostante:
'
Autore: Alessandro Alpi
'
Data: 21/08/2007 1.30
'
Lo script scrive n volte una stringa su un file
Imports System
Imports System.Data
Imports System.Math
Imports
Microsoft.SqlServer.Dts.Runtime
'
aggiungo il namespace System.IO
Imports System.IO
Public Class ScriptMain
#Region "Proprietà
Private"
' Path del file
Private ReadOnly
Property FilePath() As
String
Get
Dim str As String = Dts.Variables("FilePath").Value.ToString()
'
se la stringa è vuota sollevo un'eccezione
If String.IsNullOrEmpty(str) Then
Dts.Events.FireError(1000, "Scrivo File", "La
variabile FilePath non è valorizzata!", "",
0)
Else
Return str
End If
End Get
End Property
' Numero di
occorrenze per l'iterazione della scrittura
Private ReadOnly
Property Occurrence() As
Int16
Get
Dim occ As Int16 =
Convert.ToInt16(Dts.Variables("Occurrence").Value)
'
se le occorrenze sono <= 0 sollevo un'eccezione
If occ <=
0 Then
Dts.Events.FireError(2000, "Scrivo
File", "La variabile Occurrence
deve essere > 0!", "",
0)
Else
Return occ
End If
End Get
End Property
' Stringa da scrivere sul file
Private Property
StringToWrite() As String
Get
Return Dts.Variables("StringToWrite").Value.ToString()
End Get
Set(ByVal value As String)
Dts.Variables("StringToWrite").Value = value
End Set
End Property
#End Region
#Region "Metodi
privati"
' torna lo stream
writer del file
Private Function StreamToWrite() As
StreamWriter
' se il file
esiste già lo cancello
If
File.Exists(Me.FilePath) Then
File.Delete(Me.FilePath)
End If
' ricavo lo streamwriter
Return File.CreateText(Me.FilePath)
End Function
' scrive la
stringa n volte sul file
Private Sub WriteOnFile()
' torno lo
stream
Dim SW As StreamWriter = Me.StreamToWrite()
'
scrivo per ogni occorrenza la riga sul file
For i As Int16 = 1 To Me.Occurrence
Me.StringToWrite = Guid.NewGuid.ToString()
SW.WriteLine(Me.StringToWrite)
Next
SW.Close()
End Sub
#End Region
Public Sub Main()
' scrivo su file
Me.WriteOnFile()
Dts.TaskResult = Dts.Results.Success
End Sub
End Class
Grazie alle region il codice sarà raggruppato in questo modo:
Con l'utilizzo delle proprietà posso semplicemente gestire le eccezioni direttamente sulle variabili del pacchetto, demandando alla proprietà stessa il compito di controllare i valori che arrivano dall'esterno. Allo stesso modo, con più metodi si riesce a rendere più modulare tutto il codice e questo aiuta molto la leggibilità. Ma porta anche un grande altro vantaggio, che è quello di intervenire in una minuscola parte del listato avendo comunque la garanzia di lasciare invariato il resto.
Insomma, sono regole che per chi programma da tempo nell'ambito della OOP sono scontate e banali, ma non tutti gli utenti che usano SSIS sono skillati in questo senso.. Quindi, a volte, con poche nozioni in più, si possono ottenere risultati che facilitano gli sviluppi e la comprensione del codice.
Tutti siamo consapevoli di quanto è importante che il nostro codice possa essere letto anche dal resto del gruppo che lavora con noi, e tutti sappiamo quanto ricordiamo di quel codice dopo mesi che non leggiamo più il nostro codice, vero?
Stay Tuned!