我有一个SSIS脚本任务,该任务收集扩展的错误信息。
该脚本的内容如下:
/// <summary>
/// ScriptMain is the entry point class of the script. Do not change the name, attributes,
/// or parent of this class.
/// </summary>
[Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
Dictionary<string, string> lineageIds = null;
public void Main()
{
// Grab the executables so we have to something to iterate over, and initialize our lineageIDs list
// Why the executables? Well, SSIS won't let us store a reference to the Package itself...
Dts.Variables["User::execsObj"].Value = ((Package)Dts.Variables["User::execsObj"].Parent).Executables;
Dts.Variables["User::lineageIds"].Value = new Dictionary<string, string>();
lineageIds = (Dictionary<string, string>)Dts.Variables["User::lineageIds"].Value;
Executables execs = (Executables)Dts.Variables["User::execsObj"].Value;
ReadExecutables(execs);
Dts.TaskResult = (int)ScriptResults.Success;
}
private void ReadExecutables(Executables executables)
{
foreach (Executable pkgExecutable in executables)
{
if (object.ReferenceEquals(pkgExecutable.GetType(), typeof(Microsoft.SqlServer.Dts.Runtime.TaskHost)))
{
TaskHost pkgExecTaskHost = (TaskHost)pkgExecutable;
if (pkgExecTaskHost.CreationName.StartsWith("SSIS.Pipeline"))
{
ProcessDataFlowTask(pkgExecTaskHost);
}
}
else if (object.ReferenceEquals(pkgExecutable.GetType(), typeof(Microsoft.SqlServer.Dts.Runtime.ForEachLoop)))
{
// Recurse into FELCs
ReadExecutables(((ForEachLoop)pkgExecutable).Executables);
}
}
}
private void ProcessDataFlowTask(TaskHost currentDataFlowTask)
{
MainPipe currentDataFlow = (MainPipe)currentDataFlowTask.InnerObject;
foreach (IDTSComponentMetaData100 currentComponent in currentDataFlow.ComponentMetaDataCollection)
{
// Get the inputs in the component.
foreach (IDTSInput100 currentInput in currentComponent.InputCollection)
foreach (IDTSInputColumn100 currentInputColumn in currentInput.InputColumnCollection)
lineageIds.Add(currentDataFlowTask.ID.ToString() + currentInputColumn.ID, currentInputColumn.Name);
// Get the outputs in the component.
foreach (IDTSOutput100 currentOutput in currentComponent.OutputCollection)
foreach (IDTSOutputColumn100 currentoutputColumn in currentOutput.OutputColumnCollection)
lineageIds.Add(currentDataFlowTask.ID.ToString() + currentoutputColumn.ID, currentoutputColumn.Name);
}
}
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
}
这曾经在SQL Server 2014上正常工作。但是,由于升级到SQL Server 2017,因此该任务在行上给出以下错误消息:
MainPipe currentDataFlow = (MainPipe)currentDataFlowTask.InnerObject;
ST_47767930511349f4b94ba74c27240570中发生了'System.InvalidCastException'类型的异常,但未在用户代码中处理
其他信息:无法将类型为“ System .__ ComObject”的COM对象转换为接口类型为“ Microsoft.SqlServer.Dts.Pipeline.Wrapper.MainPipe”。此操作失败是因为由于以下错误而导致IID为“ {6D3931AC-822D-414C-8F10-7447A54BA55C}”的COM组件上的QueryInterface调用由于以下错误而失败:不支持此类接口(HRESULT异常:0x80004002(E_NOINTERFACE))
自升级到SQL Server 2017以来,还有其他人看到过吗?
答案 0 :(得分:1)
结果证明currentDataFlowTask.InnerObject返回的Com对象来自较新版本的Microsoft.SqlServer.DTSPipelineWrap。
为解决此问题,我删除了对Microsoft.SqlServer.DTSPipelineWrap的引用,并替换为同一程序集的版本14。
然后我更改了以下行:
MainPipe currentDataFlow = (MainPipe)currentDataFlowTask.InnerObject;
到
IDTSPipeline130 currentDataFlow = (IDTSPipeline130)currentDataFlowTask.InnerObject;