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

Is it possible to override a variable value calculated via an expression by passing a different value in the DTExec command line?

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

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

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

& "C:\Program Files\Microsoft SQL Server0\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 服务器中从日期时间中剥离时间的一种相当标准的方法, 只留下日期。在这种情况下,它会给出昨天 00:00 小时的日期时间)

现在,如果我使用 PowerShell 中的 DTExec 调用程序包而不设置 StartDate 变量值,它会给出正确的结果 - 昨天的数据。

有时下游流程会失败,我们会被要求重新运行 前一天的数据。因此,我希望能够使用从命令行传入的值覆盖 StartDate 的计算值。但我发现,如果我尝试从命令行设置值,该值将被忽略,表达式仍用于计算 StartDate。

有什么方法可以强制 SSIS 使用从命令行传入的值覆盖表达式值?

你正在覆盖它。问题是,每次 read/use 时都会评估 en 表达式,因此程序包启动,您指定值应该是什么,然后当 task/component 去使用该值时,执行引擎说“哦,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 日对应于 [=47 的 0 日期=] 服务器 DATETIME 数据类型?)。然而,一些谷歌搜索显示其他人发现 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;

如果我没有在命令行上明确设置 StartDateEndDate 变量,那么经过这些修改后,程序包将 运行。 SQL 查询中的 @StartDateTime 将默认为昨天 00:00 小时,而查询中的 @EndDateTime 将默认为一天后的今天早上 00:00 小时.

如果我确实在命令行上明确设置了 StartDate and/or EndDate 变量 @StartDateTime 和 [=47= 中的 @EndDateTime ] 查询将设置为 StartDate and/or EndDate 变量值。