我已经构建了一个带有两个序列容器的 ETL 包。一个用于满载,一个用于增量负载。
我希望包在每个“正常”天执行增量加载当它是执行完整加载的星期日时
我需要为此使用脚本任务吗?
有几种不同的方法可以解决这个问题。
第一种方法是通过每个序列容器上的表达式。表达式将控制容器的禁用状态,您要查找的表达式是工作日的DATEPARTdw
是星期天吗?
DATEPART("weekday", getdate()) == 1
不是星期天吗?
DATEPART("weekday", getdate()) != 1
使用 getdate 方法的问题在于测试——你将如何测试所有可能的场景?您是否要更改计算机上的时钟以验证星期日/非星期日分支是否正常工作?
我将创建一个名为CurrentDate
DateTime 类型的 SSIS 变量并将其初始化为今天。
我将创建一个名为IsSunday
Boolean 类型的第二个 SSIS 变量,并将该变量上的表达式设置为DATEPART("weekday", @[User::CurrentDate] ) == 1
然后我会修改我的两个序列容器,使其在禁用状态上有一个新的简化表达式
是星期天吗@[User::IsSunday]
不是星期天吗!@[User::IsSunday]
运行包并验证非星期日分支是否亮起(今天是星期四)。停止执行,然后将@[User::CurrentDate] 的值更改为上周日(2019-11-17)并重新启动包。验证 Sunday 分支亮起,然后停止执行。
现在您已经掌握了逻辑,剩下的步骤是修改 SSIS 变量 CurrentDate 使其上有一个getdate()
. 重新启动包并验证非星期日分支再次亮起以执行。
恭喜,你的包已经实现并且运行良好。直到没有。服务器维护窗口运行时间很长,这个包直到星期一早上 12:15 才真正开始运行 操作员如何才能告诉包“运行周日逻辑?” 你不是,除非你编辑包并且没有人愿意这样做。
在这种情况下,我可以使用上面构建的基本构造,但现在,我将向包中添加一个布尔类型的参数,并将其命名为类似ForceSunday
的,默认值为 False。只有在我需要强制星期日逻辑的情况下,才会将其翻转为 True(并且仅适用于一个运行时,而不是设计时更改)。
IsSunday 的逻辑变得更加复杂,因为我们需要 OR||
参数名称的逻辑。
DATEPART("weekday", getdate()) == 1 || @[$MyPackage::ForceSunday]
我想我的参数名称语法是正确的,但美元符号可能在其他地方(这一切都来自记忆)
这是一个非常复杂的包。让每个人的生活更轻松 - 复制并粘贴到具有周日逻辑和非周日逻辑的包中。
无论您采用哪种方法,您将遇到的下一个问题是这两个容器之间的优先约束进入屏幕右侧的容器。实线绿线是Success
和的优先约束 - 因此,只有在周日和非周日工作流程都执行Logical AND
时,最后一个框才会开始。从逻辑上讲,这不可能发生,因此您需要双击该行并将其更改为逻辑 OR
有很多方法可以做到这一点。一种相当直接的方法是在Execute SQL Task
你的两个前面Sequence Containers
加上一些代码来确定星期几。
其意图非常明确:
SELECT
CASE
WHEN DATENAME(WEEKDAY, GETDATE()) = 'Sunday' THEN 1
ELSE 0
END;
将结果集设置为Single Row
,然后在Result Set
选项卡上将查询输出分配给变量。
创建一个Precedence Constraint
从任务到增量容器。将约束编辑为 anExpression and Constraint
并指定@[User::MyVariable]==0
.
为完整刷新容器创建另一个约束,但将变量值指定为1
.
首先,谢谢你的回答。
我可能已经找到了另一种更容易的方法,但我想和你一起检查一下。在服务器管理器中,我可以创建具有内置计划的作业,可以在工作日和周末执行。所以我做了两份工作,周末价值为假,一周价值为真。如果我在序列容器上设置以下参数会起作用: 在 SSDT 中,我为完整加载序列设置了一个参数:ForceExecutionValue = false 在 SSDT 中,我为增量加载序列设置了一个参数:ForceExecutionValue = true
这会起作用还是仍然会执行这两个序列?