【问题标题】:Is it possible to override a variable value calculated via an expression by passing a different value in the DTExec command line?是否可以通过在 DTExec 命令行中传递不同的值来覆盖通过表达式计算的变量值?
【发布时间】:2020-09-27 05:38:28
【问题描述】:

是否可以通过在 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 用从命令行传入的值覆盖表达式值?

【问题讨论】:

    标签: sql-server ssis dtexec


    【解决方案1】:

    你正在覆盖它。问题是,每次读取/使用该表达式时都会评估它,因此程序包启动时,您指定值应该是什么,然后当任务/组件使用该值时,执行引擎会说“哦,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"
    

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

    【讨论】:

      【解决方案2】:

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

      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;
      

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

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

      【讨论】:

        猜你喜欢
        • 2021-06-15
        • 1970-01-01
        • 1970-01-01
        • 2011-04-02
        • 1970-01-01
        • 1970-01-01
        • 2012-11-02
        • 1970-01-01
        • 2020-01-11
        相关资源
        最近更新 更多