多数据集总行为零时如何阻止SSRS报表执行及邮件发送
解决SSRS双数据集无数据时阻止邮件发送的方案
核心思路
新增一个轻量的校验数据集,仅统计两个主数据集的总行数,避免重复执行耗时的主查询逻辑;当总行数为0时抛出16级错误(SSRS会因该错误终止报表执行,进而阻止邮件发送)。
具体实现步骤
1. 封装主查询逻辑(避免重复执行慢脚本)
把两个主数据集的查询逻辑封装成表值函数(TVF),让主数据集和校验数据集复用同一逻辑,无需重复执行复杂SQL:
-- 示例:封装第一个主数据集的查询为表值函数 CREATE FUNCTION dbo.GetExceptionData1(@Param1 DATETIME, @Param2 INT) RETURNS TABLE AS RETURN ( -- 这里是原主数据集1的复杂查询逻辑 SELECT Column1, Column2 FROM YourTable WHERE DateRange = @Param1 AND Category = @Param2 ) -- 同理封装第二个主数据集的查询 CREATE FUNCTION dbo.GetExceptionData2(@Param1 DATETIME, @Param2 INT) RETURNS TABLE AS RETURN ( -- 原主数据集2的复杂查询逻辑 SELECT ColumnA, ColumnB FROM AnotherTable WHERE DateRange = @Param1 AND Type = @Param2 )
2. 创建校验用存储过程
编写存储过程,接收报表运行参数,调用表值函数统计总行数,判断为0时抛错:
CREATE PROCEDURE dbo.ValidateReportData @Param1 DATETIME, @Param2 INT AS BEGIN SET NOCOUNT ON; DECLARE @TotalRows INT; -- 统计两个数据集的总行数(仅计数,速度远快于返回全量数据) SELECT @TotalRows = (SELECT COUNT(*) FROM dbo.GetExceptionData1(@Param1, @Param2)) + (SELECT COUNT(*) FROM dbo.GetExceptionData2(@Param1, @Param2)); -- 无数据时抛出16级错误,触发SSRS终止执行 IF @TotalRows = 0 BEGIN RAISERROR('No data to report.', 16, 1); END END
3. 配置SSRS报表
- 新增一个数据集(命名为
ValidateData),设置其查询为执行上述存储过程,并传入已知的运行参数。 - 调整数据集执行顺序:将
ValidateData设为第一个执行的数据集(可在数据集属性的「执行顺序」中调整)。这样校验不通过时,报表会立即终止,不会执行后续主数据集,也不会发送邮件。 - 修改原有的两个主数据集,调用对应的表值函数获取数据:
SELECT * FROM dbo.GetExceptionData1(@Param1, @Param2)
为什么之前的方法无效?
- 除零错误属于警告级错误,SSRS不会因此终止报表执行,仍会发送邮件。
- 使用
CountRows("DataSet1") + CountRows("DataSet2")这类报表函数,仅能在表达式中判断,但无法触发SSRS的致命错误——SSRS只有在数据集执行阶段抛出16级及以上错误时,才会终止订阅并阻止邮件发送。
内容的提问来源于stack exchange,提问作者High Plains Grifter
相关产品推荐
相关产品推荐

