是否可以通过在DTExec命令行中传递不同的值来覆盖通过表达式计算的变量值



是否可以通过在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"

当下游系统出现故障时,您可以显式更改赋值中的值并进行修补,以便使用它。

我可以通过进行以下修改来做到这一点:

  1. 去掉为变量StartDate和EndDate设置的表达式。最初我将值留空,但在保存并重新打开包后,我发现SSIS已将值默认为1899年12月30日。非常奇怪的日期(为什么不1899年12月31日,甚至1900年1月1日对应于SQL Server DATETIME数据类型的0日期?(。然而,一些谷歌搜索显示,其他人发现SSIS使用了相同的默认日期。所以这不是我偶然设置的;

  2. 在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;

在这些修改之后,如果我没有在命令行上显式设置StartDateEndDate变量,包就会运行。SQL查询中的@StartDateTime将默认为昨天00:00,查询中的@EndDateTime将默认为一天后,即今天上午00:00。

如果我确实在命令行上显式设置了StartDate和/或EndDate变量,则SQL查询中的@StartDateTime@EndDateTime将设置为StartDate和/或EndDate变量值。

相关内容

  • 没有找到相关文章

最新更新