【发布时间】:2021-04-01 12:46:01
【问题描述】:
我有一个带有 ID 的名称表
Create table Names (
Id int,
Name nvarchar(500)
)
我正在尝试创建一个过程,如果提供了 Id,它将选择 1 个与提供的 Id 匹配的名称,如果没有提供 Id,则选择所有名称
Create Procedure SelectNames
@Id int = null
AS
BEGIN
Select * From Names
Where IsNull(@Id, 0) = 0
Or Id = @Id
END
GO
但我收到一个错误:“错误:SR0015:Microsoft.Rules.Data:确定性函数调用 (ISNULL) 可能会导致不必要的表扫描。”
在这种情况下,“不必要的表扫描”指的是什么?
还有没有更好的方法来编写程序?
【问题讨论】:
-
为什么要使用
ISNULL,而不仅仅是WHERE @ID IS NULL OR...? -
另外,对于这样的“catch-all”/“Kitchen sink”查询,
OPTION (RECOMPILE)不会出错。 -
"
ISNULL用于@Id 参数。" 我知道...但是为什么要使用它呢?这不是必需的。有用于检查值是否为NULL的运算符;IS NULL和IS NOT NULL -
这不会发生。如果您将
NULL传递给@ID,则将返回all 行。ID = NULL将永远是真的,所以你所说的没有意义。 -
...
Where @Id = null是不是WHERE @ID IS NULL。NULL不等于任何东西,也不等于任何东西;包括NULL。= NULL、> NULL、< NULL、<> NULL等永远不会是 TRUE,并且总是会返回 UNKNOWN。将相等性与NULL进行比较的唯一方法是使用IS NULL和IS NOT NULL。
标签: sql-server sql-server-2017