我正在使用C#和SQL Server 2012以编程方式生成和执行SSIS包。生成的每个包都包含一个数据流任务,其中包含一个用于读取CSV的平面文件源和一个连接到SQL Server的OLE DB目标。在它们之间是一个连接了SSIS变量的行计数组件。
包执行结束后,我想将Row Count中的值返回到调用应用程序。
似乎简单地创建变量&代码中的行计数如下:
[...]
// Row count: Create a package variable to store the row count value
var ssisRowCountVariable = package.Variables.Add("MySsisVar", false, "User", 0);
// Row count: Create Row component
IDTSComponentMetaData100 componentRowCount = dataFlowTask.ComponentMetaDataCollection.New();
componentRowCount.Name = "RowCount";
componentRowCount.ComponentClassID = "DTSTransform.RowCount.4";
// Row count: Get row count design-time instance, and initialize component
CManagedComponentWrapper instanceRowCount = componentRowCount.Instantiate();
instanceRowCount.ProvideComponentProperties();
// Row count: Set the variable name property
instanceRowCount.SetComponentProperty("VariableName", "User::MySsisVar");
// Hooking up pipeline Paths
[...]
// Execute package
package.Execute()
然后在包执行后尝试读取值:
int Rows = Convert.ToInt32(ssisRowCountVariable.Value);
不起作用。
如何将Row Count组件的值返回给调用应用程序?
在尝试了第二种方法之后,我发现最好的方法似乎是连接问题中描述的Row Count组件,并添加代码使其在值设置或更改时触发事件:
ssisRowCountVariable.RaiseChangeEvent = true;
现在设置一个从标准DefaultEvents类派生的事件处理程序来捕获OnVariableValueChanged事件:
class MySsisEvents : DefaultEvents
{
public int Rows { get; private set; }
public override void OnVariableValueChanged(DtsContainer DtsContainer, Variable variable, ref bool fireAgain)
{
this.Rows = Convert.ToInt32(variable.Value);
}
}
必须修改对package.Execute()
的调用以挂接事件处理程序,如下所示:
// Execute package
var mySsisEventHandler = new MySsisEvents();
package.Execute(null, null, mySsisEventHandler, null, null);
已处理的行数现在可用作mySsisEventHandler.Rows
。
不幸的是,您无法直接从package.Execute()
调用中获取Package变量的运行时值。但是,您获取已处理记录数的任务可以通过以下方式之一以不同的方式实现:
- 向Package添加一个任务,该任务将已处理行变量中的值保存到某些存储中。任务可以在DataFlow之后,也可以在其PostExecute处理程序中
存储可以是SQL数据库或其他类似Web服务的东西;值将与执行SQL任务(针对SQL DB)或脚本任务/Web服务任务- 使用DataFlow标准的PostExecute信息消息
[SSIS.Pipeline] Information: "<your destination name>" wrote N rows.
执行MSDN中描述的包捕获事件,然后检查结果 - 使用DataFlow标准的PostExecute信息消息
请注意,只有当您在SSIS中以package.Execute
的形式运行包而不使用SSIS目录时,第二种方法才有效。如果您自己生成包,并在生成后立即执行它,则可以,您不是在生成和部署SSISDB项目。