Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 将参数与空值进行比较_Sql_Sql Server_Database_Tsql_Where Clause - Fatal编程技术网

Sql 将参数与空值进行比较

Sql 将参数与空值进行比较,sql,sql-server,database,tsql,where-clause,Sql,Sql Server,Database,Tsql,Where Clause,我是SQL新手,我想知道解决这个小问题的方法 Select * from ApplicationData where ApplicationId = @AppID AppID可以为null,也可以包含一些值。当收到null值时,它返回所有应用程序。我们有没有办法修改Where子句 范例 Select * from ApplicationData where Case When <some condition> then ApplicationId = @AppID else Ap

我是SQL新手,我想知道解决这个小问题的方法

Select * from ApplicationData where ApplicationId = @AppID
AppID可以为null,也可以包含一些值。当收到null值时,它返回所有应用程序。我们有没有办法修改Where子句

范例

Select * from ApplicationData where  Case When <some condition> then
ApplicationId = @AppID else ApplicationId is null;
从ApplicationData where Case When然后选择*
ApplicationId=@AppID,否则ApplicationId为空;
谢谢

试试这个:

SELECT *
FROM ApplicationData
WHERE CASE WHEN @AppID IS NULL THEN ApplicationId IS NULL
           ELSE ApplicationId = @AppID END;
或者,您可以将其分为以下两种情况:

SELECT * 
FROM ApplicationData
WHERE ApplicationId = @AppID
   OR (ApplicationId IS NULL AND @AppID IS NULL);
这应该起作用:

SELECT * FROM ApplicationData
WHERE (ApplicationId IS NULL AND @AppID IS NULL) OR ApplicationId = @AppID
这是另一种方法:

SELECT * FROM ApplicationData 
WHERE ISNULL(ApplicationId, -1) = ISNULL(@AppID, -1)

这些查询(一起运行时)的成本分别为34%/66%,因此请使用第一个查询。

如果在存储过程中执行此操作,请使用逻辑在两个筛选器要求之间切换。但是,只有在索引中包含ApplicationId列(最好是作为第一个键)时,这才会为您提供最佳代码

IF @AppID IS NULL
BEGIN
    SELECT * FROM ApplicationData
END
ELSE
BEGIN
    SELECT * FROM ApplicationData WHERE ApplicationId = @AppID
END
为什么这是最好的解决方案?因为SQL引擎将为此存储过程创建两个查询计划。查询计划将为您提供两个过滤要求的最佳解决方案。由于它们是小语句,并且只需要两种可能的结果,因此不会对查询缓存造成任何负担,而且代码可读性很强。如果您的需求更复杂,过滤有很多变化,那么您应该考虑动态SQL.

如果不使用存储过程,则应用程序层应动态创建两个单独的查询字符串


关于这个问题已经有很多文章了。如果您需要,我可以为您找出一些好的参数。

在考虑之前,请务必先检查您的参数,记住,括号非常重要,尤其是对于多个参数

Select * from ApplicationData 
where (@AppID IS NULL OR ApplicationId = @AppID)
OR (@AnotherAppID IS NULL OR AnotherApplicationId = @AnotherAppID )
--单个参数的示例

Select * from ApplicationData where (@AppID IS NULL OR ApplicationId = @AppID)
--多个参数的示例


确保您已经覆盖了您的参数,那么您的查询将正常工作,cheel=)

对于您的情况,您应该这样做

IF @AppID IS NULL
BEGIN
   SELECT * FROM ApplicationData WHERE ApplicationId is null
END
ELSE
BEGIN
   SELECT * FROM ApplicationData WHERE ApplicationId = @AppID
END

如果在接收null时返回所有记录,会出现什么问题?从我的角度来看,将该字段设置为null似乎不是一个好主意,因为它看起来像表的键。也就是说,在bunsess层中处理此类内容比在查询中更好,但这只是我的意见…我只需要包含空值的数据。所以当@AppID中的值为空时,您希望返回包含空值的行?如果在ApplicationId上定义了索引,情况会怎样?@MihaiBejenariu,那么问题出在哪里?该索引会与您的条件一起使用吗?第一部分@AppID为空,因此所有记录都为真将被包括在内(无论如何都是完全扫描),并且当@AppId有一个具体的值时,将使用索引吗?这是一个很酷的想法,但它总是进行两次检查。我想在时使用
CASE会稍微有效一些。如果在ApplicationId上定义了索引,情况会怎样?当@AppId有一个非空值时,会使用索引吗?@MihaiBejenariu:会使用索引,但很可能是一个完全扫描而不是查找。有没有方法写入此查询以便考虑索引?有趣的解决方案。如果你有5个带5个变量的可空字段呢?这可以说是最好的方法,这是一篇关于这个主题的好文章,它讨论了优缺点和备选方案。
IF @AppID IS NULL
BEGIN
   SELECT * FROM ApplicationData WHERE ApplicationId is null
END
ELSE
BEGIN
   SELECT * FROM ApplicationData WHERE ApplicationId = @AppID
END