如何设置SSIS父包使得4个子包可以同时运行传入不同的参数值?

How to set up SSIS parent package such that 4 child packages can run at the same time with different parameter values passed in?

我创建了一个子 SSIS 包,它根据最初指定的“ProcessName”变量值执行。现在,我希望创建一个父包,以便我可以执行 4 个子包任务,这些任务具有传入的不同 ProcessName 值以并行执行。我如何维护我的子包并将不同的值传递给 4 个执行包任务中的每一个,以便 ProcessNames 变量值对于它们中的每一个都不同?我是 SSIS 的新手,如果有人可以建议或指导我如何去做,我将不胜感激。

阅读此答案的每个人请注意:此答案不是 full/complete examples/full 步骤。根据上面的评论,我现在正在 post 进行此操作,以便请求者可以看到它并开始使用。

这是很久以前我自己写的关于如何为自己做这件事的笔记。我 post 将它作为答案,因为它很有帮助而且太大而无法 post 作为评论。另外,我没有重写为自己和我正在写的东西post。

目前我找不到我的完整代码 post 完整 details/steps。 If/when我做我会post这里,不过这个应该好好详细的就what/how做吧。此外,这还提供了有关如何处理子包错误捕获的信息。


-- 我为自己保存的笔记 posting 作为答案:

创建子包的步骤:

  1. 创建子包中需要的任何变量

  2. 在父包中创建对应的变量名(名称不必相同,可能想给它起个名字来标识它是子包变量)

子包:

  1. 需要设置:包配置 一种。右键单击包并单击包参数 b.单击复选框以启用包配置

  2. 点击添加并设置参数: 一种。配置类型:Pareknt 包变量 b.直接指定配置设置:把子包要访问的父变量名放在这里 C。点击下一步” d.在“对象”中 window 向下滚动到您从上面 select 编辑的父变量名称设置的变量,然后单击该变量名称属性下的“值”选项 e.点击下一步” F。在 Configuration Name 下:设置这个变量的详细名称 is/does.

  3. 错误处理(注意:这不是必需的,但如果不这样做,您将不会捕获子错误消息): 一种。转到事件处理程序选项卡 b.在下拉菜单下(右上角)select OnError C。添加 Scrit 任务 d.作为只读变量传递:
    System::ErrorDescription System::SourceName System::PackageName e. Copy/paste 将下面的代码放入 Main() 函数中的脚本任务中。

            ----- this is for the error handling
            public void Main()
            {
    
                // build our the error message
                string ErrorMessageToPassToParent = "Package Name:  " + Dts.Variables["System::PackageName"].Value.ToString() + Environment.NewLine + Environment.NewLine +
                    "Step Failed On:  " + Dts.Variables["System::SourceName"].Value.ToString() + Environment.NewLine + Environment.NewLine +
                    "Error Description:  " + Dts.Variables["System::ErrorDescription"].Value.ToString();
    
    
    
                // have to do this FIRST so you can access variable without passing it into the script task from SSIS tool box
                // Populate collection of variables. This will include parent package variables.
                Variables vars = null;
                Dts.VariableDispenser.GetVariables(ref vars);
    
    
                // checks if this variable exists in parent first, and if so then will set it to the value of the child variable 
                //  (do this so if parent package does not have the variable it will not error out when trying to set a non-existant varaible)
                if (Dts.VariableDispenser.Contains("OnError_ErrorDescription_FromChild") == true)
                {
    
                    // Lock the to and from variables. 
                    // parent variable
                    Dts.VariableDispenser.LockForWrite("User::OnError_ErrorDescription_FromChild");
    
                    // Need to call GetVariables again after locking them. Not sure why - perhaps to get a clean post-lock set of values.
                    Dts.VariableDispenser.GetVariables(ref vars);
    
                    // Set parentvar = childvar
                    vars["User::OnError_ErrorDescription_FromChild"].Value = ErrorMessageToPassToParent;
    
                    vars.Unlock();
                }
    
                Dts.TaskResult = (int)ScriptResults.Success;
            }
    

父包:

  1. 添加此变量以正确捕获子错误消息(不是必需的,但如果不这样做,则不会捕获 chidl 错误消息): 变量:OnError_ErrorDescription_FromChild

  2. 错误处理(注意:这不是必需的,但如果不这样做,您将不会捕获子错误消息): 一种。转到事件处理程序选项卡 b.在下拉菜单下(右上角)select OnError C。添加 Scrit 任务 d.作为只读变量传递: User::OnError_ErrorDescription_FromChild e. Copy/paste 将下面的代码放入 Main() 函数中的脚本任务中。

            ----- this is for the error handling
            public void Main()
            {            
                // get the varaible from the parent package for the error
                string ErrorFromChildPackage = Dts.Variables["User::OnError_ErrorDescription_FromChild"].Value.ToString();
    
                // do a check if the value is empty or not (so we knwo if the error came from the child package or the occurent in the parent package itself
                if (ErrorFromChildPackage.Length > 0)
                {
                    // Then raise the error that was created in the child package
                    Dts.Events.FireError(0, "Capture Error From Child Package Failure",
                            ErrorFromChildPackage   
                            , String.Empty, 0);
    
                    //Dts.TaskResult = (int)ScriptResults.Failure;
    
                } // end if the error length of variable is > 0
    
    
                Dts.TaskResult = (int)ScriptResults.Success;
            }
    

备注:

  1. 错误处理: 一种。编写子包错误处理,因此如果父包中不存在变量或错误处理,它不会失败。

    b.  If you include the error handling (and variable) in the parent package it MUST exist in the child package though.
    

我会将其视为如下模式

这里的“技巧”是在每个序列容器 SEQC 中,我需要定义保存我的参数值的变量。该变量需要限定在容器范围内 - 否则,只有一个 SSIS 变量,并且尝试初始化该值的 4 个进程将发生冲突。

在 SSIS 变量菜单中,有一个移动变量图标(列出的第二个)

在这里你可以看到我在“SEQC Opt 1a”和“SEQC Opt 1b”中都定义了 ParameterValue 并且它们被初始化为不同的值。

序列容器中的第一步是执行 SQL 任务,我在其中拉回预期的参数值。也许在您的情况下不需要,但拥有 运行 时间值的存储库可能会有所帮助。在 1b 的情况下,这更像是我的执行模式。我有一个查询,将任何包拉回此容器范围内的 运行 和起始值。例如

ContainerName|PackageName|StartingValue SEQC 选项 1a |Child0.dtsx|100 SEQC 选项 1a |Child1.dtsx|200 SEQC 选项 1a |Child2.dtsx|300 SEQC 选项 1b |Child5.dtsx|600 SEQC 选项 1b |Child6.dtsx|700 SEQC 选项 1b |Child7.dtsx|800

这个 table 模式允许我以并行和串行方式动态地 运行 包。假设上述集合中的 Child7 和 Child2 非常慢,但其他 4 个包相对较快。速度快的会启动,完成他们的工作并完成接下来的 运行 秒。一次可以触发多少个并行操作是有限制的,所以你不能无限地跨进程扩展,所以串行和并行操作的平衡是有意义的。

一旦您的模式适用于一个序列容器:复制、粘贴、重命名并假设您根据上面显示的任务名称在 table 中查找,就可以开始了。