1

我创建了一个 SSIS 包

在数据流任务中,我有几列

在此处输入图像描述

现在我将第 0 列和第 3 列的数据类型转换为int,故意创建一个错误: 在此处输入图像描述

现在我将错误配置为:

在此处输入图像描述

之后我保留了一个数据查看器并执行了包,毫不奇怪我得到了预期的错误输出:

在此处输入图像描述

我可以看到我还有 3 列

但我的问题是:

  1. 错误列是 101 和 73。如何获得正确的列名?
  2. 如何将其他信息添加到同一个错误输出表中:包 ID、包名称等
4

1 回答 1

1

这在 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://www.andrewleesmith.co.uk/2017/02/24/finding-the-column-name-of-an-ssis-error-output-error-column-id/

这是基于: http ://toddmcdermid.blogspot.com/2016/04/finding-column-name-for-errorcolumn.html

我很感激我们不应该只发布链接,但是这个解决方案非常复杂,我试图通过从 Todd 和 Andrew 的博客文章中提取信息并在此处重新创建它们来进行总结。(如果你读过这篇文章,谢谢你们!)

从托德的页面:

  1. 转到“输入和输出”页面,然后选择“输出 0”节点。将“SynchronousInputID”属性更改为“无”。(这会将脚本从同步更改为异步。)
    1. 在同一页面上,打开“Output 0”节点并选择“Output Columns”文件夹。按“添加列”按钮。将此新列的“名称”属性更改为“LineageID”。
    2. 再次按下“添加列”按钮,将“DataType”属性更改为“Unicode string [DT_WSTR]”,将“Name”属性更改为“ColumnName”。
    3. 转到“脚本”页面,然后按“编辑脚本”按钮。将此代码复制并粘贴到 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 编号转换为有意义的列名。

但是对于那些确实想了解上述脚本在做什么的人:

  1. 它正在获取附加到脚本组件的“第一个”(也是唯一的)输入。
    1. 它正在获取与输入相关的虚拟输入。“输入”是脚本实际上可以在输入上“看到”的内容 - 由于我们没有将任何列标记为“只读”或“读写”......这意味着输入没有列。但是,“虚拟输入”具有存在的每一列的完整列表,无论我们是否说过我们正在“使用”它。
    2. 然后我们遍历这个虚拟输入上的所有“虚拟列”,并且对于每一个......
    3. 获取 LineageID 和列名,并将它们作为我们异步脚本的新行推出。

Andrew 页面中的图像和文本有助于更详细地解释它:

在此处输入图像描述

然后将此映射与沿错误路径向下的 ErrorColumn 沿袭 ID 合并连接,以便错误信息可以附加到映射中的列名称。我包含了第二个脚本组件,它从错误代码中查找错误描述,因此我们在上面看到的错误表行包含列名和错误描述。

需要解释的剩余组件是条件拆分——这只是为了向创建地图的脚本组件提供元数据。我创建了一个表达式 (1 == 0),对于“No Rows – Metadata Only”路径,它的计算结果始终为 false,因此没有行会沿着它向下移动。

虽然此解决方案确实需要在数据流中插入一些额外的管道,但当确实发生错误时,我们会记录非常有价值的信息。因此,特别是当数据流在生产环境中无人看管地运行时——当我们在设计时没有可用的工具和技术来找出问题所在时——结果日志记录为我们提供了关于问题所在和原因的更精确的信息,与简单地给我们失败的数据并让我们弄清楚它被拒绝的原因相比。

于 2018-10-10T09:00:09.110 回答