如何使用SSRS参数的NULL值检索包含NULL的行
场景说明
我查阅了许多关于NULL和SSRS报表参数的文章,但都未能解决我的问题。我有一个用户可选择的SSRS报表参数@NoteType,其值可以是1、3、4或NULL。操作的数据库表eventText中有一个NoteValue列,存储上述4种值之一,无法修改表结构用整数替代NULL值。
当@NoteType为1、3或4时,报表运行正常;但当@NoteType为NULL时,报表要么无数据返回,要么返回NoteValue为1、3或4的所有行,无法获取NoteValue为NULL的行。
参数配置
已将@NoteType参数配置为允许NULL值,以Note Value为参数值字段,Note Type为标签字段,参数值通过UNION查询获取:
SELECT ett.NoteValue AS [Note Value], ett.NoteDescription AS [Note Type] FROM eventTextType ett UNION SELECT NULL AS [Note Value], 'Blank' AS [Note Type] ORDER BY [Note Type]
eventTextType表仅有3行,NoteValue值分别为1、3、4,无NoteValue为NULL的行,但eventText表中有大量此类行,因此使用UNION查询将NULL作为@NoteType的可选值之一。
UNION查询的输出如下:
Note Value Note Type 4 Annuity 1 Balance NULL Blank 3 Division
尝试过的WHERE子句
WHERE et.NoteValue = @NoteType-- 当@NoteType为1、3或4时正常,但@NoteType为NULL时无数据返回WHERE et.NoteValue = IIF(@NoteType IS NULL, NULL, @NoteType)-- 结果同上WHERE et.NoteValue = CASE WHEN @NoteType IS NULL THEN NULL ELSE @NoteType END-- 结果同上(与IIF写法等效)WHERE et.NoteValue = COALESCE(@NoteType, et.NoteValue)-- 当@NoteType为1、3或4时正常,但@NoteType为NULL时仅返回NoteValue为1、3或4的行,不返回NoteValue为NULL的行
核心问题是SQL中NULL无法用=进行比较,必须通过IS NULL判断。推荐两种可行的WHERE子句写法:
写法一:分支逻辑判断
WHERE (@NoteType IS NULL AND et.NoteValue IS NULL) OR (@NoteType IS NOT NULL AND et.NoteValue = @NoteType)
逻辑清晰直接:当参数为NULL时,匹配NoteValue为NULL的行;当参数是具体数值时,匹配对应数值的行。
写法二:用函数统一NULL转换
如果使用SQL Server(支持ISNULL函数),可以将NULL转换为一个不存在的特殊值,再进行等值比较:
WHERE ISNULL(et.NoteValue, -1) = ISNULL(@NoteType, -1)
这里选择-1是因为原数据NoteValue的取值为1、3、4,不会出现-1,既保证NULL与NULL能匹配,也不影响正常数值的查询。如果是其他数据库,可替换为对应函数:MySQL用IFNULL,Oracle用NVL。
内容的提问来源于stack exchange,提问作者BRW

