Purpose: Fetch all the user variables that are in the SSIS package and write the variable name and their values in a SQL Server 2008 table.
What have I tried: I got a small "Script Task" working to Display the variable name and their value. The script is as follows.
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
namespace ST_81ec2398155247148a7dad513f3be99d.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()
{
Microsoft.SqlServer.Dts.Runtime.Application app = new Microsoft.SqlServer.Dts.Runtime.Application();
Package pkg = app.LoadPackage(
@"C:\package.dtsx",
null);
Variables pkgVars = pkg.Variables;
foreach (Variable pkgVar in pkgVars)
{
if (pkgVar.Namespace.ToString() == "User")
{
MessageBox.Show(pkgVar.Name);
MessageBox.Show(pkgVar.Value.ToString());
}
}
Console.Read();
}
}
}
What needs to be done: I need to take this and dump the values to a database table. I am trying to work on a script component for this, but due to lack of knowledge of .net scripting, I havent gotten anywhere close to the finish line. This is what I have done on the component side.
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
using Microsoft.SqlServer.Dts;
using System.Windows.Forms;
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
public override void CreateNewOutputRows()
{
#region Class Variables
IDTSVariables100 variables;
#endregion
variables = null;
this.VariableDispenser.GetVariables(out variables);
foreach(Variable myVar in variables)
{
MessageBox.Show(myVar.Value.ToString());
if (myVar.Namespace == "User")
{
Output0Buffer.ColumnName = myVar.Value.ToString();
}
}
}
}
I can think of 2 ways of solving this issue right now .
- Use the same script task to insert the values into the Database
- using Foreach loop to enumerate the ssis package variables ( as you have asked )
Table Script for inserting the variable name and value is
CREATE TABLE [dbo].[SSISVariables]
(
[Name] [varchar](50) NULL,
[Value] [varchar](50) NULL
)
1.Use Script task
and write the below code
[System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
private static string m_connectionString = @"Data Source=Server Name;
Initial Catalog=Practice;Integrated Security=True";
public void Main()
{
List<SSISVariable> _coll = new List<SSISVariable>();
Microsoft.SqlServer.Dts.Runtime.Application app = new Microsoft.SqlServer.Dts.Runtime.Application();
Package pkg = app.LoadPackage(PackageLocation,Null);
Variables pkgVars = pkg.Variables;
foreach (Variable pkgVar in pkgVars)
{
if (pkgVar.Namespace.ToString() == "User")
{
_coll.Add(new SSISVariable ()
{
Name =pkgVar.Name.ToString(),
Val =pkgVar .Value.ToString ()
});
}
}
InsertIntoTable(_coll);
Dts.TaskResult = (int)ScriptResults.Success;
}
public void InsertIntoTable(List<SSISVariable> _collDetails)
{
using (SqlConnection conn = new SqlConnection(m_connectionString))
{
conn.Open();
foreach (var item in _collDetails )
{
SqlCommand command = new SqlCommand("Insert into SSISVariables values (@name,@value)", conn);
command.Parameters.Add("@name", SqlDbType.VarChar).Value = item.Name ;
command.Parameters.Add("@value", SqlDbType.VarChar).Value = item.Val ;
command.ExecuteNonQuery();
}
}
}
}
public class SSISVariable
{
public string Name { get; set; }
public string Val { get; set; }
}
Explanation:In this ,i'm creating a class which has properties Name and Val . Retrieve the package variables and their value using your code and store them in a collection List<SSISVariable>
.Then pass this collection to a method (InsertIntoTable
) which simply inserts the value into the database by enumerating through the collection .
Note :
There is a performance issue with the above code ,as for every variable
im hitting the database and inserting the value.You can use
[TVP][1]( SQL Server 2008) or stored procedure which takes
xml( sql server 2005) as input.
2.Using ForEach Loop
Design
Step 1: create a Variable VariableCollection
which is of type System.Object
and another
variable Item
which is of type String
to store the result from Foreach loop
Step 2: For the 1st script task .
VariableCollection
is used to store the Variable name and its value
Step 3: Inside the script task Main Method
write the following code
public void Main()
{
ArrayList _coll = new ArrayList();
Microsoft.SqlServer.Dts.Runtime.Application app = new Microsoft.SqlServer.Dts.Runtime.Application();
Package pkg = app.LoadPackage(Your Package Location,null);
Variables pkgVars = pkg.Variables;
foreach (Variable pkgVar in pkgVars)
{
if (pkgVar.Namespace.ToString() == "User")
{
_coll.Add(string.Concat ( pkgVar.Name,',',pkgVar.Value ));
}
}
Dts.Variables["User::VariableCollection"].Value = _coll;
// TODO: Add your code here
Dts.TaskResult = (int)ScriptResults.Success;
}
Step 4: Drag a Foreach loop and in the expression use Foreach from Variable Enumerator
Step 5:Foreach loop enumerates the value and stores it in a variable User::Item
Step 6:Inside the foreach loop drag a script task and select the variable
readonly variables User::Item
step 7: Write the below code in the main method
public void Main()
{
string name = string.Empty;
string[] variableCollection;
variableCollection = Dts.Variables["User::Item"].Value.ToString().Split(',');
using (SqlConnection conn = new SqlConnection(m_connectionString))
{
conn.Open();
SqlCommand command = new SqlCommand("Insert into SSISVariables values (@name,@value)", conn);
command.Parameters.Add("@name", SqlDbType.VarChar).Value = variableCollection[0];
command.Parameters.Add("@value", SqlDbType.VarChar).Value = variableCollection[1];
command.ExecuteNonQuery();
}
// TODO: Add your code here
Dts.TaskResult = (int)ScriptResults.Success;
}
Explanation : In the Foreach loop ,i can only enumerate one variable .So the logic is, i need to somehow pass the variable name and its value into one variable .And for this ,i have concatenated name and value
string.Concat ( pkgVar.Name,',',pkgVar.Value )
Script task in the foreach loop simply splits the variable and stores it into a array of string and then u can access the name and value using array index and store it in the database