Volcar el nombre y el valor de la variable USUARIO SSIS en la tabla de SQL Server

Propósito: Obtenga todas las variables de usuario que están en el paquete SSIS y escriba el nombre de la variable y sus valores en una tabla de SQL Server 2008.

¿Qué he probado? Tengo un pequeño "Script Tarea" trabajando para mostrar el nombre de la variable y su valor. El script es el siguiente.

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();
    }
    }

    }

Lo que hay que hacer: Necesito tomar esto y volcar los valores en una tabla de base de datos. Estoy tratando de trabajar en un componente de secuencia de comandos para esto, pero debido a la falta de conocimiento de las secuencias de comandos de .net, no he llegado a ninguna parte cerca de la línea de meta. Esto es lo que he hecho en el lado de los componentes.

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();
            }
        }
    }

}

preguntado el 27 de julio de 12 a las 22:07

1 Respuestas

Puedo pensar en 2 formas de resolver este problema ahora mismo.

  1. Use la misma tarea de secuencia de comandos para insertar los valores en la base de datos
  2. usando el bucle Foreach para enumerar las variables del paquete ssis (como lo ha pedido)

Table Script para insertar el nombre y el valor de la variable es

CREATE TABLE [dbo].[SSISVariables]
(
[Name] [varchar](50) NULL,
[Value] [varchar](50) NULL
)

1.Uso Script task y escribe el siguiente código

[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; }
   }

Explicación: en esto, estoy creando una clase que tiene las propiedades Name y Val. Recupere las variables del paquete y su valor usando su código y guárdelos en una colección List<SSISVariable> .Luego pase esta colección a un método (InsertIntoTable) que simplemente inserta el valor en la base de datos enumerando a través de la colección .

Nota:

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.Usando ForEach Loop

Diseño

enter image description here

Paso 1: crea una variable VariableCollection que es de tipo System.Object y otra variable Item que es de tipo String para almacenar el resultado del bucle Foreach

Paso 2: para la primera tarea de script.

VariableCollection se utiliza para almacenar el nombre de la variable y su valor enter image description here

Paso 3: dentro de la tarea del script Main Method escribe el siguiente código

  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;
    }

Paso 4: arrastre un bucle Foreach y en la expresión use Foreach from Variable Enumerator

enter image description here

Paso 5: el bucle Foreach enumera el valor y lo almacena en una variable User::Item

enter image description here

Paso 6:Dentro del bucle foreach, arrastre una tarea de secuencia de comandos y seleccione la variable

readonly variables   User::Item 

paso 7: escriba el siguiente código en el método principal

   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;
    }

Explicación: en el ciclo Foreach, solo puedo enumerar una variable. Por lo tanto, la lógica es que de alguna manera necesito pasar el nombre de la variable y su valor a una variable. Y para esto, concatené el nombre y el valor.

 string.Concat ( pkgVar.Name,',',pkgVar.Value )

La tarea de secuencia de comandos en el bucle foreach simplemente divide la variable y la almacena en una matriz de cadenas y luego puede acceder al nombre y el valor utilizando el índice de matriz y almacenarlo en la base de datos.

Respondido 04 ago 12, 18:08

Gracias Praveen por responder. Tiene completo sentido lo que estás haciendo. Después de hacer la pregunta aquí, me preguntaba si este enfoque registraría los valores de las variables de tiempo de ejecución. Sin probar su código, ¿podrá manejar los valores de tiempo de ejecución? - rvphx

@RajivVarma: el resultado se almacena como tipo de datos de objeto. Así que no importa cuál sea el valor de la variable, el código anterior debería funcionar. He probado con variables de cadena e int y funcionaron perfectamente bien. Praveen

Esperaba que esto hubiera funcionado como esperaba, pero no parece que lo haga. Tengo una tarea Ejecutar SQL que devuelve el recuento de una tabla y almacena ese valor de recuento en la variable. Rastreé la variable y parece que el primer método solo almacena el valor estático de la variable en lugar del tiempo de ejecución. - rvphx

@RajivVarma: en realidad tiene 2 instancias del mismo paquete ssis. Una que está ejecutando desde el entorno BIDS y la otra en el mismo entorno usando la tarea de secuencia de comandos. En la tarea de secuencia de comandos, en realidad está cargando un paquete que solo lee los metadatos (nada que hacer con el tiempo de ejecución). Así que muestra valores estáticos. - Praveen

Solo para demostrar que no estoy mintiendo, en su tarea de secuencia de comandos agregue la variable (en valor de solo lectura) que la está cambiando usando ejecutar la tarea sql (para encontrar el conteo). Ahora escriba el siguiente código MessageBox.Show (Dts. Variables [Usuario: :YourCountVariable].Value.toString()). Esto realmente imprimirá el conteo, no el valor estático. Praveen

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.