【问题标题】:Programmatically load SSIS package configurations以编程方式加载 SSIS 包配置
【发布时间】:2011-07-15 13:43:08
【问题描述】:

我正在 SSIS 中创建一个框架来从可配置文件夹加载文件并将它们与数据库中的逻辑作业相匹配。在这个作业中配置了一个包名,在 SSIS 中我在运行时执行这个包。

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

示意图: folderA -> 文件 A.1 -> 作业 A -> 为作业 A 加载包配置 -> 在作业 A 中执行包。

这可能吗?

【问题讨论】:

    标签: ssis


    【解决方案1】:

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

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

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

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

    有关更多详细信息,请在联机丛书中查看执行包任务,它将向您展示如何设置包以传递变量。

    【讨论】:

    • 感谢HLGEM,您能否详细描述一下如何通过主包动态加载包配置?
    • 不幸的是,它有点困难:您描述它的方式是通过 SQL Server 的默认包配置行为,这对我不起作用。这是我的要求:例如,对于一个子包,我有 2 个包配置。我希望主包在运行时为该子包将包配置设置为这两个包配置之一....
    • @Patrick Peters。您需要有两个父包,它们为相同的变量发送不同的值,每个配置一个。
    【解决方案2】:

    我现在找到了解决方案。只有通过使用 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;
                }
    

    【讨论】:

      猜你喜欢
      • 2014-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多