我一直在寻找一种进行 SQL 查询的好方法,在其中我可以有一个 where 语句,如果留空,它将表现得就像它根本不存在一样。我发现了这个,它似乎工作得很好:
WHERE (Column = @value OR @value is null)
如果我为@value 指定一个值,则搜索会按照我的意愿进行过滤。但是如果我传入 null,就好像说 @value 可以是任何东西。我喜欢这个。这很好。但我不明白的是,为什么会这样?
我一直在寻找一种进行 SQL 查询的好方法,在其中我可以有一个 where 语句,如果留空,它将表现得就像它根本不存在一样。我发现了这个,它似乎工作得很好:
WHERE (Column = @value OR @value is null)
如果我为@value 指定一个值,则搜索会按照我的意愿进行过滤。但是如果我传入 null,就好像说 @value 可以是任何东西。我喜欢这个。这很好。但我不明白的是,为什么会这样?
如果@value 为空,您的 WHERE 子句:
WHERE (Column = @value OR @value is null)
减少到
WHERE (Column = @value OR 1=1)
(这与if (Column == value || true)
其他常用语言类似)
如果任何一个操作数(边)为真,则 OR 连接为真:SQL 使用三值逻辑
+---------+------+---------+---------+
| A OR B | TRUE | Unknown | FALSE |
+---------+------+---------+---------+
| TRUE | TRUE | TRUE | TRUE |
| Unknown | TRUE | Unknown | Unknown |
| FALSE | TRUE | Unknown | FALSE |
+---------+------+---------+---------+
所以:
Column = @value
.嗯,有两种情况:
1) @value 是“某物”。
在这种情况下,第二个子句始终为假,因为“某事”永远不会为空。所以剩下的就是WHERE Column = @value
.
2) @value 为空
在这种情况下,第二个子句总是假的,因为 null 永远不会等于任何东西。所以实际上剩下的就是WHERE @value is null
@value 已知为空,所以这就像WHERE 1 = 1
整个 WHERE 被忽略。数据库应该足够聪明,可以在接触任何数据之前弄清楚这一点,所以这应该就像根本没有指定条件一样执行。
因此,您在这里拥有的是一个可以像两个一样运行的单个 SQL 语句,带有一个“可选的 WHERE”。对于这两种情况,两个单独的 SQL 语句相比的优势在于,在构建 SQL 语句时不需要在应用程序中使用条件逻辑(如果有多个“切换”,这会变得非常麻烦)。