如何设置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 作为答案:
创建子包的步骤:
创建子包中需要的任何变量
在父包中创建对应的变量名(名称不必相同,可能想给它起个名字来标识它是子包变量)
子包:
需要设置:包配置
一种。右键单击包并单击包参数
b.单击复选框以启用包配置
点击添加并设置参数:
一种。配置类型:Pareknt 包变量
b.直接指定配置设置:把子包要访问的父变量名放在这里
C。点击下一步”
d.在“对象”中 window 向下滚动到您从上面 select 编辑的父变量名称设置的变量,然后单击该变量名称属性下的“值”选项
e.点击下一步”
F。在 Configuration Name 下:设置这个变量的详细名称 is/does.
错误处理(注意:这不是必需的,但如果不这样做,您将不会捕获子错误消息):
一种。转到事件处理程序选项卡
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;
}
父包:
添加此变量以正确捕获子错误消息(不是必需的,但如果不这样做,则不会捕获 chidl 错误消息):
变量:OnError_ErrorDescription_FromChild
错误处理(注意:这不是必需的,但如果不这样做,您将不会捕获子错误消息):
一种。转到事件处理程序选项卡
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;
}
备注:
错误处理:
一种。编写子包错误处理,因此如果父包中不存在变量或错误处理,它不会失败。
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 中查找,就可以开始了。
我创建了一个子 SSIS 包,它根据最初指定的“ProcessName”变量值执行。现在,我希望创建一个父包,以便我可以执行 4 个子包任务,这些任务具有传入的不同 ProcessName 值以并行执行。我如何维护我的子包并将不同的值传递给 4 个执行包任务中的每一个,以便 ProcessNames 变量值对于它们中的每一个都不同?我是 SSIS 的新手,如果有人可以建议或指导我如何去做,我将不胜感激。
阅读此答案的每个人请注意:此答案不是 full/complete examples/full 步骤。根据上面的评论,我现在正在 post 进行此操作,以便请求者可以看到它并开始使用。
这是很久以前我自己写的关于如何为自己做这件事的笔记。我 post 将它作为答案,因为它很有帮助而且太大而无法 post 作为评论。另外,我没有重写为自己和我正在写的东西post。
目前我找不到我的完整代码 post 完整 details/steps。 If/when我做我会post这里,不过这个应该好好详细的就what/how做吧。此外,这还提供了有关如何处理子包错误捕获的信息。
-- 我为自己保存的笔记 posting 作为答案:
创建子包的步骤:
创建子包中需要的任何变量
在父包中创建对应的变量名(名称不必相同,可能想给它起个名字来标识它是子包变量)
子包:
需要设置:包配置 一种。右键单击包并单击包参数 b.单击复选框以启用包配置
点击添加并设置参数: 一种。配置类型:Pareknt 包变量 b.直接指定配置设置:把子包要访问的父变量名放在这里 C。点击下一步” d.在“对象”中 window 向下滚动到您从上面 select 编辑的父变量名称设置的变量,然后单击该变量名称属性下的“值”选项 e.点击下一步” F。在 Configuration Name 下:设置这个变量的详细名称 is/does.
错误处理(注意:这不是必需的,但如果不这样做,您将不会捕获子错误消息): 一种。转到事件处理程序选项卡 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; }
父包:
添加此变量以正确捕获子错误消息(不是必需的,但如果不这样做,则不会捕获 chidl 错误消息): 变量:OnError_ErrorDescription_FromChild
错误处理(注意:这不是必需的,但如果不这样做,您将不会捕获子错误消息): 一种。转到事件处理程序选项卡 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; }
备注:
错误处理: 一种。编写子包错误处理,因此如果父包中不存在变量或错误处理,它不会失败。
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 中查找,就可以开始了。