以编程方式加载SSIS包配置

时间:2011-07-15 13:43:08

标签: ssis

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

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

示意性地: folderA - >文件A.1 - >工作A - >作业A的加载包配置 - >在作业A中执行包。

这可能吗?

2 个答案:

答案 0 :(得分:3)

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

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

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

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

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

答案 1 :(得分:0)

我现在找到了解决方案。只能使用使用SSIS对象模型的脚本任务在运行时基于SQL Server Application类创建包,您可以在其中按文件名加载包。从文件加载包后,我可以通过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;
            }