以编程方式加载SSIS包配置
我正在SSIS中创建一个框架,用于从可配置文件夹加载文件,并将其与数据库中的逻辑作业相匹配。在这个作业中配置了一个包名,在SSIS中我在运行时执行这个包 我希望根据加载的作业以编程方式加载此包的包配置。SSIS SQL Server包配置不是一个选项,因为它在运行时只为包本身加载一次值到此包,但我希望在运行时加载与作业一起存储的特定包配置(作业有一个包,但有多个包配置) 示意图: 文件夹->文件A.1->作业A->加载作业A的包配置->在作业A中执行包以编程方式加载SSIS包配置,ssis,Ssis,我正在SSIS中创建一个框架,用于从可配置文件夹加载文件,并将其与数据库中的逻辑作业相匹配。在这个作业中配置了一个包名,在SSIS中我在运行时执行这个包 我希望根据加载的作业以编程方式加载此包的包配置。SSIS SQL Server包配置不是一个选项,因为它在运行时只为包本身加载一次值到此包,但我希望在运行时加载与作业一起存储的特定包配置(作业有一个包,但有多个包配置) 示意图: 文件夹->文件A.1->作业A->加载作业A的包配置->在作业A中执行包 这可能吗?我们使用父包和子包来为具有不同配
这可能吗?我们使用父包和子包来为具有不同配置值的不同客户端运行标准包。父packge使用和环境变量以及我们的配置表来获取特定进程的配置值。子表配置为接受从执行包任务中的父包发送的配置变量。这还允许我们为父包中的特定客户机执行一些定制步骤,如果需要的话(这里大约100%的时间)。因此,如果您从一个客户机获得一个文件,而他们无法以标准子导入使用的格式提供该文件,那么您可以执行转换步骤,使该文件为标准导入做好准备,然后运行该标准。或者,您可以在标准包之后添加步骤,向客户发送电子邮件,但客户需要在其数据中修复例外情况(例如,如果只有一个客户需要) 您可以在父包中为要发送的每段配置信息创建变量,通常是子包中连接的其他变量或连接字符串。然后放入一个Excute包任务,该任务使用到子包的连接 在子包中,然后转到SSIS菜单,选择包配置并添加。然后,对于配置类型,选择父包变量。您将为要发送到子包的每个配置项创建一个父包变量。我们发送的内容包括客户端id、到特定于客户端的数据库的连接字符串、可能因客户端而异的内容变量等 我们还将所有配置存储在元数据库中的一个表中,并在其中存储有关导入的信息。因此,我们将父包设置为使用环境变量告诉它要连接到哪个数据库以获取配置信息,然后第二个确认是存储配置信息的SSISConfiguration表。我们通过在测试包之前运行的插入脚本,按服务器填充这些信息(通常情况下,服务器会有所不同,dev、qa和prod的连接字符串会有所不同)
有关更多详细信息,请在联机丛书中查找执行包任务,它将向您展示如何设置包以传递变量 我现在找到了解决办法。只有使用使用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;
}
感谢HLGEM,但是您能描述一些关于如何通过主包动态加载包配置的详细信息吗?不幸的是,这有点困难:您描述它的方式是通过SQL Server的默认包配置行为,这对我不适用。这是我的要求:例如,对于一个子包,我有两个包配置。我希望主包在运行时为该子包将包配置设置为这两个包配置中的一个…@Patrick Peters。您需要有两个父包,为相同的变量发送不同的值,每个配置一个。