0

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

我有一个参数化查询,我将变量传递User::StartDate给它。包名称是 OpenAirExport.dtsx。

如果我使用 PowerShell 中的 DTExec 调用我的包,我可以在命令行上很好地设置 StartDate 变量。例如:

& "C:\Program Files\Microsoft SQL Server\150\DTS\Binn\DTExec.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 用从命令行传入的值覆盖表达式值?

4

2 回答 2

1

你正在覆盖它。问题是,每次读取/使用该 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"

当下游系统出现故障时,您可以显式更改分配中的值和补丁,以便使用它。

于 2020-09-27T06:21:47.003 回答
1

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

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

  2. 在 SSIS 包的 OLE DB 源中,我修改了接收传入参数的 SQL 命令代码。以前是:

    声明@StartDateTime DATETIME = ?;

    声明@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;

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

如果我确实在命令行上明确设置了StartDateand/or变量,那么 SQL 查询中的and将被设置为and/or变量值。EndDate@StartDateTime@EndDateTimeStartDateEndDate

于 2020-09-27T23:00:10.013 回答