SSIS条件分割触发错误的脚本组件PostExecute方法

问题描述 投票:0回答:1

我有一个正在 Visual Studio 2022 中开发的针对 SQL Server 2019 的 SSIS 包,但我遇到了一个奇怪的问题。

我有一个刷新不记名令牌的数据流,这意味着它从数据库检索令牌,检查过期时间,如果过期,则刷新它,如果未过期,则重用数据库中的令牌。然后,它将该令牌存储在包范围变量中,以便稍后在其他数据流中使用。

要更新令牌或重用令牌,我使用两个不同的脚本组件,它们通过使用以下表达式的条件拆分进行路由:

  • 输出:“令牌已过期”,表达式:
    HasExpired == TRUE
  • 输出:“令牌未过期”,表达式:
    HasExpired ==  FALSE

我遇到的问题是:我的令牌没有过期,但由于某种原因,负责更新过期令牌的脚本组件中的

void PostExecute()
被触发。我做了很多测试,似乎有时当我重新启动 VS 时它会起作用,但在运行几次后它又开始这样做了。

知道可能是什么原因造成的吗?

我尝试在脚本组件中设置断点,但错误的方法仍然不断触发。我还尝试启用数据查看器,数据查看器显示正确的数据,但仍然会触发错误的

PostExecute()

ssis script-component conditional-split
1个回答
0
投票

您可以构建一个简单的复制品,它确实显示条件分割可能正在做它应该做的事情

在这里,我生成 2 行,并将该位设置为 true 和 false,并看到正确的路径亮起。然后我将 False 行和零行路由到 Row Count 组件,它会像脚本组件一样获得绿色复选标记

如果您查看输出,您会看到一行内容

信息:DFT 演示中的 0x0,过期路径的执行后:RowsReceived = False

虽然您没有显示 PostExecute 的代码,但我愿意发布带有经过教育的猜测的答案。无论是否有任何数据点亮组件,PostExecute 事件每次都会触发。这在 SSIS 中很常见,因为它需要在自身之后进行清理,因此脚本组件中的逻辑每次都会触发,除非您告诉它不要这样做。

在下面的脚本任务中,我声明一个名为

rowsReceived
的成员变量并将其初始化为 False。

在我的 PostExecute 方法中,我向输出日志写入两次。第一条是您在我的屏幕截图中看到的消息。第二个位于 If 块内,仅当该行实际落在组件中时才会触发。

最后也是最琐碎的部分是 ProcessInputRows 方法。无论是 1 行还是 10 亿行,它们都会进行相同的评估,因为它们将我们的

rowsReceived
从 False 翻转为 True。

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

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
    bool rowsReceived;

    public override void PreExecute()
    {
        base.PreExecute();
        rowsReceived = false;
    }

    public override void PostExecute()
    {
        base.PostExecute();
        bool fireAgain = false;
        ComponentMetaData.FireInformation(0, "PostExecute of Expired path", string.Format("RowsReceived = {0}", rowsReceived), "", 0, ref fireAgain);
        if (rowsReceived)
        {
            ComponentMetaData.FireInformation(0, "PostExecute of Expired path", "DO TASK HERE TO REFRESH TOKENS", "", 0, ref fireAgain);
        }
    }

    public override void Input0_ProcessInputRow(Input0Buffer Row)
    {
        rowsReceived = true;
    }

}

将我的源查询切换回 1 false、1 true,您可以看到输出日志中显示一条新消息,该消息对应于您将在其中执行令牌刷新活动的占位符。

有道理吗?

© www.soinside.com 2019 - 2024. All rights reserved.