SQL"IS"和"="运算符有何不同?

Dan*_*ing 16 sql sqlite null equality operators

我正在构建一些使用参数化值的预准备语句.举个例子:

SELECT * FROM "Foo" WHERE "Bar"=@param
Run Code Online (Sandbox Code Playgroud)

有时@param可能会NULL.在这种情况下,我想查询返回记录,其中BarNULL的,但上面的查询不会那样做.我了解到我可以使用IS运算符.换一种说法:

SELECT * FROM "Foo" WHERE "Bar" IS @param
Run Code Online (Sandbox Code Playgroud)

除了不同的处理NULL方式之外,上述两种陈述的表现方式是否还有其他不同之处?如果@param不是NULL,但是,相反,让我们说,5IS在这种情况下使用操作员是安全(和理智)的事情吗?我应该采取其他方法吗?

小智 13

你想要来自Foo的记录,其中Bar = @param,或者如果@param为null,其中Bar为null.一些提议的解决方案将为您提供带有非空@param的空记录,这听起来不像您的要求.

Select * from Foo where (@param is null and Bar is null) or (Bar = @param)
Run Code Online (Sandbox Code Playgroud)

这并不是说这是Oracle还是SQL Server或其他RDBMS,因为它们各自实现了稍微不同的辅助函数.SQL的ISNULL(第一,第二)就像NVL(第一,第二).我喜欢SQL Server的COALESCE()以获得普遍适用性.

IS比较仅用于空比较.

如果您正在使用SQL Server,并且您确实需要一个不同的3VL逻辑真值表来解决您的问题(也就是说,如果您在某个时间点特别需要"NULL = NULL"为"true",那么在你的代码块中,你可以使用该指令,并且认识到这已被弃用并且禁止你的理由,而不是一般的好主意

SET ANSI_NULLS OFF

这是它上面的BOL:http: //msdn.microsoft.com/en-us/library/ms188048.aspx


Har*_*non 6

编辑:( 从OP更新:这不能做我的@如果@param是5,那么我想只看到Bar为5的记录.我想看看Bar为NULL的记录,当且仅当@param是如果我的问题没有说清楚,我道歉.)

在这种情况下,我认为你应该尝试这样的事情:

SELECT * FROM Foo WHERE Bar=@param OR (Bar IS NULL AND @param IS NULL)
Run Code Online (Sandbox Code Playgroud)

上一篇文章:

为什么不简单地使用OR?

SELECT * FROM "Foo" WHERE "Bar"=@param OR "Bar" IS NULL
Run Code Online (Sandbox Code Playgroud)

在SQL Server中,您可以使用ISNULL:

SELECT * FROM "Foo" WHERE ISNULL("Bar",@param)=@param
Run Code Online (Sandbox Code Playgroud)

  • 不是逆向,但是,虽然确实提供了替代方案,但实际上并没有回答OP的问题,即*IS和=运算符之间有什么区别*...... (2认同)
  • "在这种情况下,我希望查询返回Bar为NULL的记录,但上面的查询不会这样做." .."在这种情况下使用IS运算符是安全(和理智)的事情吗?我应该采取其他方法吗?" 我相信OP主要对实现这一目标的安全方式感兴趣.我真的不知道那些之间的区别,除了IS意味着NULL,我认为那是次要的问题. (2认同)

Dan*_*n J 6

您可能会错误地考虑这个问题.例如,如果您正在谈论SQL Server(因为这是我必须提供的),您的第二个示例将导致语法错误.IS右侧的值不能为5.

为了解释,请考虑MSDN对T-SQL中这两个运算符的解释(请注意,询问"SQL"和"SQL Server"不一定相同).

等于(=)运算符

IS NULL运算符

注意一些重要的事情.还有就是为"IS"运营商没有这样的事情在T-SQL.特别是<expression> IS [NOT] NULL运算符,它将单个表达式与NULL进行比较.

=运算符不同,它将两个表达式相互比较,并且当一个或两个表达式恰好为NULL时具有某些行为!