使用订阅时有趣的 SSRS 参数发现
Interesting SSRS parameter discovery when using subscriptions
我最近一直在整理一份 SSRS 报告,该报告将 运行 在前 15 分钟 'chunk' 的时间内每 15 分钟报告一次。本质上是一个非常直接和简单的报告,将 运行 通过自动订阅。
我使用的是 Microsoft SQL Server 12 Report Builder 版本 3。
当我的收件人报告发送的是空白文件时,我收到了输出 csv 问题的警告,最奇怪的是考虑到 运行 手动生成的报告按预期生成。
长话短说,这是我用来生成“从”和“到”日期的表达式。手动 运行s 产生数据,订阅 运行s 没有。
原参数
起始日期
dateadd(DateInterval.Second, (second(now()) + 900) * -1, dateadd(Dateinterval.Minute, (minute(now()) mod 15) * -1, now()))
至今
dateadd(DateInterval.Second, (second(now()) + 1) * -1, dateadd(Dateinterval.Minute, (minute(now()) mod 15) * -1, now()))
新参数
起始日期
dateadd(DateInterval.Minute, -15, dateadd(DateInterval.Minute, cint(datediff(DateInterval.Minute,today(),now()) / 15) * 15, today()))
至今
dateadd(DateInterval.Second, 899,Parameters!FromDate.Value)
以为我会post这里有两个原因
- 关于原因的理论
- 它可能会对将来的某人有所帮助
原始参数值是单独计算的,这意味着它们每个 Now()
的值都略有不同。我知道这是一个远景,但这是一个理论。如果订阅作业在 15 分钟间隔之前的几分之一秒内触发,则 ToDate
可能刚好在 FromDate
之前返回。这将导致无效的日期范围。
对于新表达式,ToDate
引用了 FromDate
,这强制它们按顺序计算,而不是并行计算。更不用说您要添加到 FromDate
中,这也会强制日期范围具有一致的长度。但是,如果 FromDate
是在 15 分钟截止时间的错误一侧计算的,您可能仍然 运行 会得到两次相同的报告。
test/avoid解决此问题的一种方法是抵消订阅时间,这样它实际上就不会尝试在确切的 15 分钟截止时间触发。例如,您可以将其安排在 1 分钟后关闭。
您的原始参数采用 Now
并减去分钟以得出 15 分钟的时间,然后它们采用另一个 Now
的秒数(稍后可能在下一秒甚至分钟)并减去该值得到 0 秒时间(或 59 秒时间)。当第一个和第二个 Now
之间的秒数发生变化时,这可能已经导致问题,这不是很奇怪,因为在我的测试系统上 [=12= 的两次评估之间有 0.59 秒] 在 FromDate 参数中。此外,Now
值比一秒钟更准确,而您的公式不符合这一点。因此,如果您在报告中尝试处理的记录正好有一刻钟的时间,则第一个参数肯定更大(可能多 0.01 秒),因此该记录将被忽略。
你的 "new parameters" 公式不依赖于 Now()
的秒数,并且总是 return 没有几分之一秒的时间,所以我想这就是差异。
FromDate 的表达式可以稍微简化一下:
=Today.AddSeconds(900*(DateDiff(DateInterval.Minute, Today, Now)-1))
如果你不打算在午夜前很短的时间内运行报告,那么Today
和[=12=的评估期间应该不会出现因日期变化引起的问题],你可以用类似的方式计算第二个参数,独立于第一个参数:
=Today.AddSeconds(900*(DateDiff(DateInterval.Minute, Today, Now))-1)
我最近一直在整理一份 SSRS 报告,该报告将 运行 在前 15 分钟 'chunk' 的时间内每 15 分钟报告一次。本质上是一个非常直接和简单的报告,将 运行 通过自动订阅。
我使用的是 Microsoft SQL Server 12 Report Builder 版本 3。
当我的收件人报告发送的是空白文件时,我收到了输出 csv 问题的警告,最奇怪的是考虑到 运行 手动生成的报告按预期生成。
长话短说,这是我用来生成“从”和“到”日期的表达式。手动 运行s 产生数据,订阅 运行s 没有。
原参数
起始日期
dateadd(DateInterval.Second, (second(now()) + 900) * -1, dateadd(Dateinterval.Minute, (minute(now()) mod 15) * -1, now()))
至今
dateadd(DateInterval.Second, (second(now()) + 1) * -1, dateadd(Dateinterval.Minute, (minute(now()) mod 15) * -1, now()))
新参数
起始日期
dateadd(DateInterval.Minute, -15, dateadd(DateInterval.Minute, cint(datediff(DateInterval.Minute,today(),now()) / 15) * 15, today()))
至今
dateadd(DateInterval.Second, 899,Parameters!FromDate.Value)
以为我会post这里有两个原因
- 关于原因的理论
- 它可能会对将来的某人有所帮助
原始参数值是单独计算的,这意味着它们每个 Now()
的值都略有不同。我知道这是一个远景,但这是一个理论。如果订阅作业在 15 分钟间隔之前的几分之一秒内触发,则 ToDate
可能刚好在 FromDate
之前返回。这将导致无效的日期范围。
对于新表达式,ToDate
引用了 FromDate
,这强制它们按顺序计算,而不是并行计算。更不用说您要添加到 FromDate
中,这也会强制日期范围具有一致的长度。但是,如果 FromDate
是在 15 分钟截止时间的错误一侧计算的,您可能仍然 运行 会得到两次相同的报告。
test/avoid解决此问题的一种方法是抵消订阅时间,这样它实际上就不会尝试在确切的 15 分钟截止时间触发。例如,您可以将其安排在 1 分钟后关闭。
您的原始参数采用 Now
并减去分钟以得出 15 分钟的时间,然后它们采用另一个 Now
的秒数(稍后可能在下一秒甚至分钟)并减去该值得到 0 秒时间(或 59 秒时间)。当第一个和第二个 Now
之间的秒数发生变化时,这可能已经导致问题,这不是很奇怪,因为在我的测试系统上 [=12= 的两次评估之间有 0.59 秒] 在 FromDate 参数中。此外,Now
值比一秒钟更准确,而您的公式不符合这一点。因此,如果您在报告中尝试处理的记录正好有一刻钟的时间,则第一个参数肯定更大(可能多 0.01 秒),因此该记录将被忽略。
你的 "new parameters" 公式不依赖于 Now()
的秒数,并且总是 return 没有几分之一秒的时间,所以我想这就是差异。
FromDate 的表达式可以稍微简化一下:
=Today.AddSeconds(900*(DateDiff(DateInterval.Minute, Today, Now)-1))
如果你不打算在午夜前很短的时间内运行报告,那么Today
和[=12=的评估期间应该不会出现因日期变化引起的问题],你可以用类似的方式计算第二个参数,独立于第一个参数:
=Today.AddSeconds(900*(DateDiff(DateInterval.Minute, Today, Now))-1)