在 WHERE 子句中使用可为空的列

发布于 2024-08-13 18:37:48 字数 563 浏览 9 评论 0原文

假设 SQL Server 中的表定义如下:

CREATE TABLE MyTable (
  Id   UNIQUEIDENTIFIER NULL,
  Info VARCHAR(MAX)
)

和一个查询:

DECLARE @id UNIQUEIDENTIFIER
DECLARE @info VARCHAR(MAX)
IF @id IS NOT NULL
BEGIN
  SELECT @info = Info
    FROM MyTable
    WHERE Id = @id
END

在这种情况下,Visual Studio 静态代码分析器会生成以下错误:

警告:SR0007: Microsoft.Performance:可为空 列可能会导致最终结果 谓词的计算结果为 NULL。

我在这里没有看到问题。该错误与性能有关; MSDN 说我应该使用 ISNULL() ——但是与 NULL 的 equals 比较总是错误的,对吧?我错过了什么,还是警告是错误的?

Assume a table definition in SQL Server as follows:

CREATE TABLE MyTable (
  Id   UNIQUEIDENTIFIER NULL,
  Info VARCHAR(MAX)
)

And a query:

DECLARE @id UNIQUEIDENTIFIER
DECLARE @info VARCHAR(MAX)
IF @id IS NOT NULL
BEGIN
  SELECT @info = Info
    FROM MyTable
    WHERE Id = @id
END

In that case, the Visual Studio static code analyzer produces the following error:

Warning : SR0007 :
Microsoft.Performance : Nullable
columns can cause final results to be
evaluated as NULL for the predicate.

I don't see the problem here. The error is related to performance; MSDN says I should use ISNULL() -- but an equals comparison against NULL is always false, right? Am I missing something, or is the warning just wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

暮凉 2024-08-20 18:37:48

我认为它指的是 WHERE 子句。这意味着您的参数和列都可以为 NULL,在这种情况下,您的 WHERE 子句的计算结果不再为 true/false。通过将可为空的列集中到始终定义值的列(通过 ISNULL),您可以在逻辑上处于更好的状态。

这是有关该错误的 Microsoft 文档。

另外,据说 NULL使查询速度变慢。

I think it's referring to the WHERE clause. It's saying that both your parameter and your column can be NULL, in which case your WHERE clause no longer evaluates to true/false. By funneling your nullable column into one that always has a value defined (via ISNULL), you're in better shape, logic-wise.

Here's the Microsoft documentation on that error.

On the aside, NULLs supposedly make queries a skosh slower.

逐鹿 2024-08-20 18:37:48

我认为分析器可能只是没有考虑您的 IF 语句。

你的代码对我来说似乎是正确的。

I think the analyzer might just not be taking into account your IF statement.

Your code seems correct to me.

╰つ倒转 2024-08-20 18:37:48

空比较取决于设置。

当 SET ANSI_NULLS 为 ON 时,所有针对 null 值的比较结果均为 UNKNOWN

当 SET ANSI_NULLS 为 ON 时,使用 WHERE column_name = NULL 的 SELECT 语句
即使 column_name 中存在空值,也会返回零行。
使用 WHERE column_name <> 的 SELECT 语句即使column_name 中没有 nnull 值,NULL 也会返回零行。

当 SET ANSI_NULLS 为 OFF 时,等于 (=) 和不等于 (<>) 比较运算符不遵循 ISO 标准.

这是来自这里

Null comparison depends on setup.

When SET ANSI_NULLS is ON, all comparisons against a null value evaluate to UNKNOWN

When SET ANSI_NULLS is ON, a SELECT statement that uses WHERE column_name = NULL
returns zero rows even if there are null values in column_name.
A SELECT statement that uses WHERE column_name <> NULL returns zero rows even if there are no nnull values in column_name.

When SET ANSI_NULLS is OFF, the Equals (=) and Not Equal To (<>) comparison operators do not follow the ISO standard.

This is from here.

清风疏影 2024-08-20 18:37:48

我认为这是一个虚假的警告 - 你能根据具体情况抑制它,或者完全抑制该特定警告吗?

当你这样做时会发生什么?:

CREATE TABLE MyTable (
  Id   UNIQUEIDENTIFIER NOT NULL,
  Info VARCHAR(MAX)
)

I think it's a spurious warning - can you suppress it on a case-by-case basis, or that particular warning completely?

What happens when you do this?:

CREATE TABLE MyTable (
  Id   UNIQUEIDENTIFIER NOT NULL,
  Info VARCHAR(MAX)
)
黑色毁心梦 2024-08-20 18:37:48
IF @id IS NOT NULL

应替换为

IF ISNull(@id, -1) <> -1
IF @id IS NOT NULL

should be replaced with

IF ISNull(@id, -1) <> -1
爱的故事 2024-08-20 18:37:48

@ Raj:“IF ISNull(@id, -1) <> -1”

我不会这样做,因为它实际上替换了表条目

@ Raj: "IF ISNull(@id, -1) <> -1"

I would not do it as it actually replaces the table entry

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文