2011-07-15 26 views
2

我正在SSIS中构建一个框架,用于从可配置文件夹加载文件并将它们匹配到数据库中的逻辑作业。在这个工作中,配置了一个包名,并且在SSIS中我在运行时执行这个包。以编程方式加载SSIS包配置

我想以编程方式加载此包的包配置,具体取决于加载的作业。 SSIS SQL Server软件包配置不是一个选项,因为它只在运行时为该软件包本身加载一次值到这个软件包,但是我想在运行时加载一个特定的软件包配置(作业有一个软件包,但有许多封装配置)....

示意: folderA - >文件A.1 - >任务A - 作业A>负载包配置 - >在工作A.执行包

是这样可能吗?

回答

0

我现在找到了解决方案。只有通过使用脚本任务使用SSIS对象模型才能在运行时创建基于SQL Server应用程序类的包,您可以在其中按文件名加载包。从文件加载包后,我可以通过xml或SQL Server从文件中读取配置,并在运行时将其添加到子包配置列表中。

两个重要注意事项:

1)家长变量不传递到子包自动。 仅当使用执行包任务时,父变量会自动传递给子代。为了得到这个工作,我在运行时搜索变量并在其中写入值,因为我知道我想要传递给每个子包的确切变量。

2)当使用SQL Server作为子包的包配置时,还必须在运行时创建连接管理器,并将其添加到包的连接管理器集合中。将包配置添加到子包时,请确保该连接管理器的名称是连接字符串的一部分。

下面是代码,以证明它的工作原理:

//load the information of the job into these variables. Package is the File system deployed package on a share. Package configuration can be the package configuration in an xml file on a share, or a connection string when using SQL Server (this one is used here). 
      string package = this.Dts.Variables["Package"].Value.ToString(); 
      string packageConfiguration = this.Dts.Variables["PackageConfiguration"].Value.ToString(); 


      //create a package from package factory, by file. 
      Microsoft.SqlServer.Dts.Runtime.Application app = new Microsoft.SqlServer.Dts.Runtime.Application(); 
      Package packageToRun = app.LoadPackage(package, null); 

      //------------------------------------------ CHILD PACKAGE VARIABLES PASSING 
      packageToRun.EnableConfigurations = true; 

      //add one extra package configuration for child package specific configuration 
      Configuration config = packageToRun.Configurations.Add(); 
      config.Name = "MyConfig"; 
      config.ConfigurationType = DTSConfigurationType.SqlServer; 
      config.ConfigurationString = packageConfiguration; 

      //use the name 'MyConnectionManager' in your packageConfiguration 
      ConnectionManager cm = packageToRun.Connections.Add("OleDb"); 
      cm.Name = "MyConnectionManager"; 
      //TODO: retrieve this from an environvariable to allow change in data source for DEV, QA, PROD, now temporarly fixed to this value 
      cm.ConnectionString = "Data Source=.;Initial Catalog=YYYYYYYYYY;Provider=SQLNCLI10.1;Integrated Security=SSPI;"; 

      //For Parent-Child var passing, I used the technique to let all the parent variables being defined in the child packages. 
      //Other technique could be to allow the child package not define the parent variables, but then the child packages have to reference them from code 

      //------------------------------------------ PARENT VARIABLES PASSING 
      //Now check if these parent variables exist in child package and write the actual values in them 
      try 
      { 
       Variables vars = null; 
       VariableDispenser variableDispenser = packageToRun.VariableDispenser; 

       if (
        packageToRun.Variables.Contains("User::XXXXXXXXXXXX") && 
        ) 
       { 
        packageToRun.VariableDispenser.LockForWrite("User::XXXXXXXXXXXX"); 

        variableDispenser.GetVariables(ref vars); 

        packageToRun.Variables["User::XXXXXXXXXXXX"].Value = this.Dts.Variables["User::XXXXXXXXXXXX"].Value; 

        vars.Unlock(); 

        packageToRun.Execute(); 

        Dts.TaskResult = (int)ScriptResults.Success; 
       } 
       else 
       { 
        this.Dts.Events.FireError(0, string.Empty, "Child package: " + package + " has no required master variables defined or unable to unlock.", string.Empty, 0); 
       } 
      } 
      catch (Exception ex) 
      { 
       this.Dts.Events.FireError(0, string.Empty, ex.Message, string.Empty, 0); 

       Dts.TaskResult = (int)ScriptResults.Failure; 
      } 
3

我们使用父代和子代包执行一些simliar操作,为具有不同配置值的不同客户端运行标准程序包。父包使用并环境变量和我们的配置表来获取特定进程的配置值。子表配置为接受从执行包任务中的父包发送的配置变量。如果需要的话,这也允许我们为父包中的特定客户端执行一些自定义步骤(这是大约100%的时间)。因此,您可以从一个客户端获得一个文件,而这些客户端无法以标准子导入使用的格式提供,您可以执行转换步骤来为标准导入准备文件,然后运行该标准。或者,您可以在standrd软件包之后添加步骤,以便向客户端发送电子邮件,并且例外情况下需要修复它们的数据,例如,如果只有一个客户端需要这样做。

您可以在父包中为要发送的每条配置信息创建变量,通常将其发送给子包中的conmnections的其他变量或连接字符串。然后,您将放入一个执行包任务,该任务使用到子包的连接。

在子包中,然后转到SSIS菜单并选择包配置和添加。然后,对于配置类型,选择父包变量。您将为要发送到Child包的每个配置项创建一个Parent包变量。我们发送的东西是client_id,客户端特定数据库的连接字符串,可能因客户端而异的事物的变量等。

我们还将所有配置存储在元数据库中的表中,我们存储信息关于进口。因此,我们设置父pacakge以使用环境变量来告诉它要连接哪个数据库以获取配置信息。然后,第二个配置是存储配置信息的SSISConfiguration表。我们通过在测试软件包之前运行的插入脚本,通过服务器填充这些信息(它通常会因服务器而异,连接字符串对于dev,qa和prod不同)。

有关更多详细信息,请参阅联机丛书以获取执行包任务,并向您展示如何设置包以传递变量。

+0

感谢HLGEM,但你可以描述一些细节如何动态地加载由主机套餐套餐配置? –

+0

不幸的是,它有点难度:你描述它的方式是通过SQL Server的默认包配置行为,它不适合我。这是我的要求:对于一个孩子包,我有两个包装配置,例如。我希望主包将该包配置设置为运行时为这个子包提供的这2个包配置中的一个...。 –

+0

@Patrick Peters。您需要有两个父包,它们为相同的变量发送不同的值,每个配置一个。 – HLGEM