是否可以通过在DTExec命令行上传递不同的值来覆盖SSIS包中通过表达式计算的变量的值?
我有一个参数化查询,并将变量User::StartDate
传递给它。包名为OpenAirExport.dtsx.
如果我使用PowerShell中的DTExec调用包,我可以在命令行上设置StartDate变量fine。例如:
& "C:Program FilesMicrosoft SQL Server150DTSBinnDTExec.exe" -File 'OpenAirExport.dtsx' `
-Set 'Package.Variables[User::StartDate].Properties[Value];2020-09-22'
这很好用。从由此产生的数据中,我可以看出,开始日期确实设定为2020年9月22日。
然而,99%的情况下,该包只会获得前一天的数据。所以我在StartDate变量上设置了一个表达式来计算它的值:
DATEADD("day", DATEDIFF("day", (DT_DBTIMESTAMP)0, GETDATE()) - 1, (DT_DBTIMESTAMP)0)
(这个看起来相当复杂的表达式只计算自第0天以来的天数,然后将它们添加到第0天并减去1。这是SQL Server中从日期时间中剥离时间的一种相当标准的方法,只保留日期。在这种情况下,它将给出昨天00:00的日期时间(
现在,如果我使用PowerShell中的DTExec调用包,而不设置StartDate变量值,它将给出正确的结果-昨天的数据。
下游流程时不时会失败,我们会被要求重新运行前一天的数据。因此,我希望能够用从命令行传入的值覆盖StartDate的计算值。但我发现,如果我尝试从命令行设置值,该值将被忽略,并且该表达式仍用于计算StartDate。
有什么方法可以强制SSIS用从命令行传入的值重写表达式值吗?
您正在重写它。问题是,每次读取/使用en表达式时都会对其求值,这样包就会启动,您可以指定该值,然后当任务/组件使用该值时,执行引擎会说"哦,StartDate上面有一个表达式。让我们对它进行评估,以防值发生变化">
一个更简单的选择是从@StartDate中完全删除该表达式。设置为最小(或最大(日期值,如果包在Posh脚本的标准机制之外运行,则该值不应执行任何操作。有了故障保险,你就有了的标准启动
-Set 'Package.Variables[User::StartDate].Properties[Value];$RunDate'
其中$RunDate是预先计算的。
$RunDate = Get-Date -Format "yyyy-MM-dd"
# If we need to manually adjust start date, uncomment this line and use the right date
# $RunDate = "2020-09-22"
当下游系统出现故障时,您可以显式更改赋值中的值并进行修补,以便使用它。
我可以通过进行以下修改来做到这一点:
-
去掉为变量StartDate和EndDate设置的表达式。最初我将值留空,但在保存并重新打开包后,我发现SSIS已将值默认为1899年12月30日。非常奇怪的日期(为什么不1899年12月31日,甚至1900年1月1日对应于SQL Server DATETIME数据类型的0日期?(。然而,一些谷歌搜索显示,其他人发现SSIS使用了相同的默认日期。所以这不是我偶然设置的;
-
在SSIS包的OLE DB源中,我修改了接收传入参数的SQL命令代码。以前是:
DECLARE@StartDateTime DATETIME=?;
DECLARE@EndDateTime DATETIME=?;
我把它改成:
DECLARE @DefaultDateTime DATETIME = '1899-12-30';
DECLARE @StartDateParameter DATETIME = ?;
DECLARE @StartDateTime DATETIME = @StartDateParameter;
IF COALESCE(@StartDateParameter, @DefaultDateTime) = @DefaultDateTime
BEGIN;
-- Default to 00:00 hours yesterday.
SET @StartDateTime = DATEADD(day, DATEDIFF(day, 0, GETDATE()) - 1, 0);
END;
DECLARE @EndDateParameter DATETIME = ?;
DECLARE @EndDateTime DATETIME = @EndDateParameter;
IF COALESCE(@EndDateParameter, @DefaultDateTime) = @DefaultDateTime
BEGIN;
-- Default to 1 day after start date.
SET @EndDateTime = DATEADD(day, 1, @StartDateTime);
END;
在这些修改之后,如果我没有在命令行上显式设置StartDate
和EndDate
变量,包就会运行。SQL查询中的@StartDateTime
将默认为昨天00:00,查询中的@EndDateTime
将默认为一天后,即今天上午00:00。
如果我确实在命令行上显式设置了StartDate
和/或EndDate
变量,则SQL查询中的@StartDateTime
和@EndDateTime
将设置为StartDate
和/或EndDate
变量值。