我创建了一个 SSIS 包
在数据流任务中,我有几列
现在我将第 0 列和第 3 列的数据类型转换为int,故意创建一个错误:
现在我将错误配置为:
之后我保留了一个数据查看器并执行了包,毫不奇怪我得到了预期的错误输出:
我可以看到我还有 3 列
但我的问题是:
- 错误列是 101 和 73。如何获得正确的列名?
- 如何将其他信息添加到同一个错误输出表中:包 ID、包名称等
这在 SS2016 及更高版本中很容易: https ://www.mssqltips.com/sqlservertip/4066/retrieve-the-column-causing-an-error-in-sql-server-integration-services/
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
Row.ErrorDescription = this.ComponentMetaData.GetErrorDescription(Row.ErrorCode);
IDTSComponentMetaData130 componentMetaData = this.ComponentMetaData as IDTSComponentMetaData130;
Row.ErrorColumnName = componentMetaData.GetIdentificationStringByID(Row.ErrorColumn);
}
对于在 SS2016 之前使用 SQL Server 版本的任何人,这里有几个参考链接,用于获取列名称:
这是基于: http ://toddmcdermid.blogspot.com/2016/04/finding-column-name-for-errorcolumn.html
我很感激我们不应该只发布链接,但是这个解决方案非常复杂,我试图通过从 Todd 和 Andrew 的博客文章中提取信息并在此处重新创建它们来进行总结。(如果你读过这篇文章,谢谢你们!)
从托德的页面:
- 转到“输入和输出”页面,然后选择“输出 0”节点。将“SynchronousInputID”属性更改为“无”。(这会将脚本从同步更改为异步。)
- 在同一页面上,打开“Output 0”节点并选择“Output Columns”文件夹。按“添加列”按钮。将此新列的“名称”属性更改为“LineageID”。
- 再次按下“添加列”按钮,将“DataType”属性更改为“Unicode string [DT_WSTR]”,将“Name”属性更改为“ColumnName”。
- 转到“脚本”页面,然后按“编辑脚本”按钮。将此代码复制并粘贴到 ScriptMain 类中(您可以删除所有其他方法存根):
public override void CreateNewOutputRows() {
IDTSInput100 input = this.ComponentMetaData.InputCollection[0];
if (input != null)
{
IDTSVirtualInput100 vInput = input.GetVirtualInput();
if (vInput != null)
{
foreach (IDTSVirtualInputColumn100 vInputColumn in vInput.VirtualInputColumnCollection)
{
Output0Buffer.AddRow();
Output0Buffer.LineageID = vInputColumn.LineageID;
Output0Buffer.ColumnName = vInputColumn.Name;
}
}
} }
随意使用数据查看器将虚拟输出附加到该脚本,看看你得到了什么。从这里开始,它是您 ETL 专家的“标准工程”。只需将失败组件的错误输出与此元数据合并,您就可以将 ErrorColumn 编号转换为有意义的列名。
但是对于那些确实想了解上述脚本在做什么的人:
- 它正在获取附加到脚本组件的“第一个”(也是唯一的)输入。
- 它正在获取与输入相关的虚拟输入。“输入”是脚本实际上可以在输入上“看到”的内容 - 由于我们没有将任何列标记为“只读”或“读写”......这意味着输入没有列。但是,“虚拟输入”具有存在的每一列的完整列表,无论我们是否说过我们正在“使用”它。
- 然后我们遍历这个虚拟输入上的所有“虚拟列”,并且对于每一个......
- 获取 LineageID 和列名,并将它们作为我们异步脚本的新行推出。
Andrew 页面中的图像和文本有助于更详细地解释它:
然后将此映射与沿错误路径向下的 ErrorColumn 沿袭 ID 合并连接,以便错误信息可以附加到映射中的列名称。我包含了第二个脚本组件,它从错误代码中查找错误描述,因此我们在上面看到的错误表行包含列名和错误描述。
需要解释的剩余组件是条件拆分——这只是为了向创建地图的脚本组件提供元数据。我创建了一个表达式 (1 == 0),对于“No Rows – Metadata Only”路径,它的计算结果始终为 false,因此没有行会沿着它向下移动。
虽然此解决方案确实需要在数据流中插入一些额外的管道,但当确实发生错误时,我们会记录非常有价值的信息。因此,特别是当数据流在生产环境中无人看管地运行时——当我们在设计时没有可用的工具和技术来找出问题所在时——结果日志记录为我们提供了关于问题所在和原因的更精确的信息,与简单地给我们失败的数据并让我们弄清楚它被拒绝的原因相比。