Giorni fa su
dotnethell.it, mi è arrivata una domanda (e non è la prima) in cui un utente si chiedeva di che tipo fossero gli oggetti resultset tornati da un
Execute SQL Task.
Ebbene, non è molto chiaro in effetti
.
All'inizio un po' tutti si aspettano un tipo .net, ma non è così. Proviamo a fare un esempio, partendo dalla creazione di una tabella e qualche riga sul db:
USE tempdb;
CREATE TABLE dbo.Records
(
ID int identity(1,1) NOT NULL PRIMARY KEY CLUSTERED
, Valore varchar(10) NOT NULL
)
GO
INSERT INTO dbo.Records (Valore)
VALUES ('UNO')
INSERT INTO dbo.Records (Valore)
VALUES ('DUE')
INSERT INTO dbo.Records (Valore)
VALUES
('TRE')
GO
A questo punto andiamo a leggere con un semplice SSIS il contenuto della tabella. Creiamo un semplice package come il seguente:
Ho creato un connection manager al tempdb del mio server e lo statement è una semplice select di un campo Valore dalla tabella precedentemente creata.
Come si può notare nel rettangolo verde, impostiamo nella proprietà ResultSet il valore Full result set per ottenere l'oggetto in output.
Successivamente, spostiamoci nella sezione resultset e, facendoci aiutare dalla voce "<New Variable..>" andiamo a creare il seguente resultset mapping:
Non abbiamo fatto altro che creare la variabile contenitore del resultset ed ora entriamo più in dettaglio, cercando di capire come trovarne il tipo.
Prima di tutto aggiungiamo uno script task nel package, andando a mettere questo codice all'interno (C# e VB.Net, vale anche per SSIS 2005):
C#
/*
Microsoft SQL Server Integration Services Script Task
Write scripts using Microsoft Visual C# 2008.
The ScriptMain is the entry point class of the script.
*/
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
namespace ST_87c655ab011a4c68be47eb840ea7e680.csproj
{
[System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
public partial class ScriptMain :
Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
#region VSTA generated code
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
public void Main()
{
MessageBox.Show(String.Format("Il tipo dell'oggetto è: {0}",Dts.Variables["User::ResultSetVariable"].Value.GetType()));
Dts.TaskResult = (int)ScriptResults.Success;
}
}
}
VB.Net
' Microsoft SQL Server Integration
Services Script Task
' Write scripts using Microsoft
Visual Basic 2008.
' The ScriptMain is the entry point
class of the script.
Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime
<System.AddIn.AddIn("ScriptMain",
Version:="1.0", Publisher:="", Description:="")> _
<System.CLSCompliantAttribute(False)> _
Partial Public Class ScriptMain
Inherits
Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
Enum ScriptResults
Success
= Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success
Failure
= Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
End Enum
Public Sub Main()
MessageBox.Show(String.Format("Il tipo dell'oggetto è: {0}",
Dts.Variables("User::ResultSetVariable").Value.GetType()))
Dts.TaskResult = ScriptResults.Success
End Sub
End Class
Il SSIS creato è il seguente:
Eseguendolo noterete che il tipo dell'oggetto letto dall'Execute SQL Task è
System.__ComObject. O meglio, un vero e proprio recordset ADO. Quindi non risulta possibile usare oggetti .net per castarvi questo resultset. Il modo migliore per leggerlo è utilizzare un Foreach Enumerator con l'enumeratore di tipo ADO. Via script risulterebbe piuttosto scomodo. Alcuni si sono chiesti, ma come mai allora non esiste un Recordset Source mentre abbiamo un Recordset Destination? Per questo potete dare una letta a questo interessante
post di Jamie Thomson. Appoggio pienamente le sue motivazioni
.
Stay Tuned!