如何设置 SSIS 父包,使 4 个子包可以同时运行,传入不同的参数值?
Posted
技术标签:
【中文标题】如何设置 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? 【发布时间】:2021-09-10 15:21:23 【问题描述】:我创建了一个子 SSIS 包,它根据最初指定的“ProcessName”变量值执行。现在,我希望创建一个父包,以便我可以执行 4 个子包任务,其中传入不同的 ProcessName 值以并行执行。如何维护我的子包并将不同的值传递给 4 个执行包任务中的每一个,以使每个执行包的 ProcessNames 变量值都不同?我是 SSIS 的新手,如果有人能给我建议或指导我如何去做,我将不胜感激。
【问题讨论】:
如果您确定 4 个子包不会相互干扰(不知道它们在做什么,或者可能会回答这个问题),但您可以向子包添加 4 个调用以同时运行/平行。 每个子包将一个表从一个 sql server 传输到另一个。我相信他们不会互相干扰。如何将 4 个不同的值传递给子包?我应该使用什么?提前感谢您的回答:) 在父包中设置变量,然后将每个变量(使用不同的值)传递给对子包的 4 个不同调用中的每一个。 对不起这不是说我必须手动编辑每个子包以从父包中获取不同的变量吗?不太确定它是如何动态的。有没有我可以参考的资源来更好地理解? 我一定误解了您最初的问题,我以为您只是在问如何同时执行 4 个子程序,而不是如何将变量传递给子程序包。为此,我必须找到代码。这与使用不同值多次调用 SP 的概念相同。您创建 SP(或在您的情况下为子包)以接受变量。然后将变量传递给子包,设置单个变量,该变量是动态的并且会发生变化,因为您将不同的值从父包传递给它。我知道这很令人困惑,我会尝试找到我的完整考试代码 【参考方案1】:我会将其视为如下模式
这里的“技巧”是在每个序列容器 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
此表模式允许我以并行和串行的方式动态运行包。假设上述集合中的 Child7 和 Child2 非常慢,但其他 4 个包相对较快。快速的将启动,完成他们的工作并完成下一次运行。一次可以触发多少个并行操作是有限制的,因此您无法跨进程无限扩展,因此串行和并行操作的平衡是有意义的。
一旦您的模式适用于一个序列容器:复制、粘贴、重命名并假设您根据上面显示的任务名称在表中查找,就可以开始了。
【讨论】:
【参考方案2】:阅读此答案的每个人的注意事项:此答案不完整/包含示例/完整步骤。根据上面的评论,我现在发布此内容,以便请求者可以看到并开始。
这是我很久以前自己写的关于如何为自己做这件事的笔记。我将其发布为答案,因为它很有帮助且太大而无法作为评论发布。另外,我没有重写任何为自己写的东西和我要发布的东西。
目前我找不到完整的代码来发布完整的详细信息/步骤。如果/当我这样做时,我会在这里发布,但这应该是关于做什么/如何做的很好的细节。此外,这还提供了有关如何处理子包错误捕获的信息。
-- 我为自己保存的笔记作为答案发布:
创建子包的步骤:
在子包中创建任何需要的变量
在父包中创建对应的变量名(名称不必相同,可能需要命名以将其标识为子包变量)
儿童套餐:
需要设置:包配置 一种。右键单击包,然后单击包参数 湾。单击复选框以启用包配置
点击添加并设置参数: 一种。配置类型:Pareknt 包变量 湾。直接指定配置设置:把子包要访问的父变量名放在这里 C。点击下一步” d。在“对象”窗口中,从上面选择的父变量名称向下滚动到您正在设置的变量,然后单击该变量名称的“属性”下的“值”选项 e.点击下一步” F。在配置名称下:设置此变量的详细名称/作用。
错误处理(注意:这不是必需的,但如果您不这样做,您将不会捕获子错误消息): 一种。转到事件处理程序选项卡 湾。在下拉菜单(右上角)下选择 OnError C。添加脚本任务 d。作为只读变量传递: 系统::错误描述 系统::源名称 系统::包名 e.将以下代码复制/粘贴到 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;
父包:
添加此变量以正确捕获子错误消息(不是必需的,但如果不这样做,您将不会捕获 chidl 错误消息): 变量:OnError_ErrorDescription_FromChild
错误处理(注意:这不是必需的,但如果您不这样做,您将不会捕获子错误消息): 一种。转到事件处理程序选项卡 湾。在下拉菜单(右上角)下选择 OnError C。添加脚本任务 d。作为只读变量传递: 用户::OnError_ErrorDescription_FromChild e.将以下代码复制/粘贴到 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;
注意事项:
对于错误处理: 一种。编写子包错误处理,如果父包中不存在变量或错误处理,则不会失败。
b. If you include the error handling (and variable) in the parent package it MUST exist in the child package though.
【讨论】:
以上是关于如何设置 SSIS 父包,使 4 个子包可以同时运行,传入不同的参数值?的主要内容,如果未能解决你的问题,请参考以下文章
SSIS教程:创建简单的ETL包 -- 5. 添加包部署模型的包配置(Adding Package Configurations for the Package Deployment Model)(代
SSIS onTaskfailed/OnErrorfailed 事件,无法捕获最近的错误
SSIS教程:创建简单的ETL包 -- 4. 增加错误处理流程(Adding Error Flow Redirection)