如何获取有关 SSIS 查找中哪个查找失败的更多信息?

jor*_*npg 4 ssis ssis-2012

我经常遇到以下错误

Error: 0xC020901E at Build Test Data, Lookup ID String[120]: Row yielded no match during lookup.
Run Code Online (Sandbox Code Playgroud)

为了解决这些问题,我将回到源头并进行明智的猜测,但如果我能看到失败的行,那就容易多了。

在 SSIS 中执行此操作的最佳方法是什么(使用 MSSQL2012)?

谢谢。

bil*_*nkc 8

我遇到过的任何东西都没有为此提供开箱即用的功能,如果有人证明我错了,我会很高兴。

因此,我所做的是一个可控的失败。

受控故障 00

我对 DimEmployee 的查找应该总是匹配。在执行此依赖包之前,数据已加载到该表中。源数据没有机会在加载之间改变,但我仍然遇到查找结果不匹配的情况。不,这不是一个迟到的维度,只是他们对需求的理解很差。

无论如何,我所做的是将不匹配设置为“将行重定向到无匹配输出”。对于 2005 年的那些人,您将不得不使用“将行重定向到错误输出”

在此处输入图片说明

然后我计算有多少行从失败的查找中流出,因为如果有一个失败,可能会有更多。即使查找可以捕获该行失败,这也是一个缺点 - 它只会向您显示第一行,我通常想知道所有失败。

受控故障

我为此使用了一个脚本任务,当我输入它时,我可以看到如何将它变成一个可重用的组件......我的脚本任务充当转换,但我可以很容易地指定一个目标。我在查找中使用的列中进行了映射,但没有产生匹配项。对于这个例子,我有一个EmployeeID和他们的EffectiveDT

我将在这个组件中做的是为每一个通过的行触发一个警告事件。SSISDB 中运行的 2012 项目的默认设置将捕获警告事件。一旦所有行都通过,在我的PostExecute方法中,我将引发Error事件,这将导致整个 DataFlow 失败。

using System;
using System.Collections.Generic;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
    /// <summary>
    /// Variable identifying whether we had any rows
    /// </summary>
    bool Found;    

    /// <summary>
    /// Initialize our variable
    /// </summary>
    public override void PreExecute()
    {
        base.PreExecute();
        this.Found = false;
    }

    /// <summary>
    /// Error out the entire task if we found any rows
    /// </summary>
    public override void PostExecute()
    {
        base.PostExecute();

        if (this.Found)
        {
            bool cancel = true;
            ComponentMetaData.FireError(0, "SCR Lookup Employee", "Unmatched Employees found. See warning for more context", string.Empty, 0, out cancel);
        }
    }

    /// <summary>
    /// Emit warnings for all the bad rows and then flag the entire operation as having bad rows
    /// </summary>
    /// <param name="Row">The row that is currently passing through the component</param>
    public override void Input0_ProcessInputRow(Input0Buffer Row)
    {
        this.Found = true;
        string msg = string.Format("Research->{0}:{1}", Row.EmployeeID, string.Format("{0:yyyy-MM-dd}", Row.EffectiveDT));

        ComponentMetaData.FireWarning(0, "Unmatched Employees", msg, string.Empty, 0);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我在服务器上运行我的包并观察执行/操作 ID。如果您进入 SSMS 中的“所有执行”报告,则这是第一列 ID 中的值。在这种情况下,我看到 938 所以我然后在 SSISDB 中运行以下查询

USE SSISDB;
SET NOCOUNT ON;

DECLARE
    @operation_id bigint = 938;

WITH SRC AS
(
    SELECT
        OM.message
    ,   CHARINDEX('->', OM.message) AS arrow
    ,   CHARINDEX(':', OM.message, CHARINDEX('->', OM.message)) AS colon
    ,   LEN(OM.message) AS length
    ,   RIGHT(OM.message, LEN(OM.message) - CHARINDEX('->', OM.message) -1) AS elements
    FROM
        catalog.operation_messages AS OM
    WHERE
        OM.message_type= 110
        AND OM.message_source_type = 60
        AND OM.message LIKE '%research%'
        AND OM.operation_id = @operation_id
)
, PARSED AS
(
    SELECT
        SRC.message
    ,   CHARINDEX(':', SRC.elements) AS colon
    ,   LEN(SRC.elements) AS length
    ,   SRC.elements AS RelevantText
    ,   LEFT(SRC.elements, CHARINDEX(':', SRC.elements) -1) AS EmployeeID
    ,   RIGHT(SRC.elements, LEN(SRC.elements) - CHARINDEX(':', SRC.elements)) AS EventDate
    FROM
        SRC
)
SELECT
    P.message
,   P.RelevantText 
,   P.EmployeeID
,   P.EventDate
FROM
    PARSED AS P;
Run Code Online (Sandbox Code Playgroud)

这将为我提供我在“所有消息”报告中看到的所有相关部分,但优点是我可以单击并选择内容,而且我已经解析出我需要的内容。

message RelevantText    EmployeeID  EventDate
DFT Load FactPayroll:Warning: Research->90132693:2011-05-25 90132693:2011-05-25 90132693    2011-05-25
DFT Load FactPayroll:Warning: Research->900432371:2011-05-25    900432371:2011-05-25    100432371   2011-05-25
DFT Load FactPayroll:Warning: Research->900443209:2011-05-25    900443209:2011-05-25    100443209   2011-05-25
DFT Load FactPayroll:Warning: Research->900443418:2011-05-25    900443418:2011-05-25    100443418   2011-05-25
Run Code Online (Sandbox Code Playgroud)

以交互模式运行

如果您是从 Visual Studio/SSDT/BIDS 的上下文中运行它,我什至不会担心脚本的输出,只需添加一个数据查看器,然后您就不必担心爬取日志。

替代修改您的包(2012+)

2012 年发布的 SSIS 为我们提供了一种用于对已部署的包进行故障排除的新工具:Data Taps。这些是每次执行的机制,允许您在数据流中的特定点生成 CSV(仅)提取。这在高度监管的环境 (SOX/SAS 70/HIPPA/PCI) 中非常有用,在这些环境中,您不能在没有地球上每个人的签字的情况下部署更新的包。只需运行带有特殊位集的包,它就会在一个众所周知的位置生成一个 CSV。

对于上面引用的屏幕截图,如果我想查看将要命中“LKP DimEmployee”的所有源数据,我会标识我的 PackagePath:\Package\DFT Load FactJobAction和我的 IdentificationString:Paths[ALL DateSK.Union All Output 1]然后使用 Josh 文章中的脚本

USE SSISDB;

DECLARE @ExecutionID  BIGINT 

/*****************************************************************************
--  First create an execution instance.  Data taps are valid for the specified
--  execution instance only
*****************************************************************************/
EXEC catalog.create_execution 
        N'DW Folder',  --Folder name in SSISDB 
        N'DW Project', --Project name in SSISDB
        N'FactJobAction', --Package name in SSISDB
        NULL, --optional parameter to hold reference ID for later use
        0, --optional  parameter set to 1 if 32-bit runtime required
        @ExecutionID OUTPUT;

DECLARE @DataTapID BIGINT;

/******************************************************************************
--  Next create the actual data tap.  The parameters specified below deterimine
--  at which point in a specific package the data tap will be added.  
******************************************************************************/
EXEC catalog.add_data_tap
        @ExecutionID, --output from catalog.create_execution
        N'\Package\DFT Load FactJobAction', --PackagePath property value from data flow task in SSDT
        N'Paths[ALL DateSK.Union All Output 1]', --IdentificationString property value from data flow task in SSDT
        N'File.csv', --Desired Output file name
        NULL, --optional paramter to specify number of rows to log. NULL for all rows
        @DataTapID OUTPUT; --output ID


/******************************************************************************
--  This final block of code executes the package.  The data tap file output 
--  will be found in the %SSISRoot%\DataTaps directory upon completion
******************************************************************************/
EXEC catalog.start_execution 
        @ExecutionID;  --output from catalog.create_execution
Run Code Online (Sandbox Code Playgroud)