我正在构建一些使用参数化值的预准备语句。举个例子:
SELECT * FROM "Foo" WHERE "Bar"=@param
有时@param
可能是NULL
。在这种情况下,我希望查询返回Bar
为NULL
的记录,但上述查询不会这样做。我了解到我可以使用IS
运算符。换句话说:
SELECT * FROM "Foo" WHERE "Bar" IS @param
除了NULL
的不同处理方式之外,上述两种陈述的表现方式是否还有其他方式?如果@param
不是NULL
,而是让我们说5
,该怎么办?在这种情况下使用IS
运算符是一个安全(和理智)的事情吗?我还有其他方法吗?
答案 0 :(得分:12)
你想要来自Foo的记录,其中Bar = @param,或者如果@param为null,其中Bar为null。一些提议的解决方案将为您提供带有非空@param的空记录,这听起来不像您的要求。
Select * from Foo where (@param is null and Bar is null) or (Bar = @param)
这并不是说这是Oracle还是SQL Server或其他RDBMS,因为它们各自实现了稍微不同的辅助函数。 SQL的ISNULL(第一,第二)就像NVL(第一,第二)。我喜欢SQL Server的COALESCE()以获得普遍适用性。
IS比较仅适用于空比较。
如果您正在使用SQL Server,并且确实需要一个不同的3VL逻辑真值表来解决您的问题(也就是说,如果您特别需要“NULL = NULL”为“真的“在某个时间点,并且也认识到这是不赞成的,并且除了你的理由,一般不是一个好主意”,在你的代码块中你可以使用指令
SET ANSI_NULLS OFF
这是BOL: http://msdn.microsoft.com/en-us/library/ms188048.aspx
答案 1 :(得分:6)
编辑: (从OP更新:这不能做我的@param是5,然后我想只看到Bar为5的记录。我想看看Bar是NULL的记录,当且仅当@param是NULL。如果我的问题没有说清楚,我道歉。)
在这种情况下,我认为你应该尝试这样的事情:
SELECT * FROM Foo WHERE Bar=@param OR (Bar IS NULL AND @param IS NULL)
上一篇文章:
为什么不简单地使用OR?
SELECT * FROM "Foo" WHERE "Bar"=@param OR "Bar" IS NULL
在SQL Server中,您可以使用ISNULL:
SELECT * FROM "Foo" WHERE ISNULL("Bar",@param)=@param
答案 2 :(得分:6)
您可能会错误地考虑这个问题。例如,如果您正在谈论SQL Server(因为这是我必须提供的),您的第二个示例将导致语法错误。 IS右侧的值不能为5。
为了解释,请考虑MSDN对T-SQL中这两个运算符的解释(请注意,询问“SQL”和“SQL Server”不一定相同)。
注意一些重要的事情。 在T-SQL中没有“IS”运算符这样的东西。特别是<expression> IS [NOT] NULL
运算符,它将单个表达式与NULL进行比较。
这与<{1}}运算符不一样,它将两个表达式相互比较,并且在一个或两个表达式中具有某些行为碰巧是NULL!
答案 3 :(得分:3)
我不知道您使用的是哪个版本的SQL,但IS在您刚才描述的上下文中没有任何意义。如果我尝试按照您描述的方式使用它,我会收到语法错误。你为什么要在=之上使用它?这是常见的用法,也是软件维护者希望找到的。
答案 4 :(得分:2)
您使用的是哪种特定数据库?
如果您正在进行基于null(或非null)的搜索,那么使用IS是可行的方法。我无法提供技术原因,但我一直使用这种语法。
SELECT * FROM Table WHERE Field IS NULL
SELECT * FROM Table WHERE Field IS NOT NULL