首先让我说我完全知道sql server不会短路评估。如果由于执行计划而认为合适,“可以”,但最好不要猜测。SQL Server在这种特定情况下是否会一直短路?
我想知道,如果它可以在关于空任何特定情况下强制 - 如所有的客户在此查询
declare @customerId int set @customerId = null select * from customer where ((@customerId Is Null) Or [email protected])
客户编号动态载荷是PK(INT),不能为空
问题:有谁知道在这种情况下引擎是否总是选择左侧,或者如果我们确实最终会检查每行的右侧是否为CustomerId = null。 我猜这不能保证工作,因为右侧可能是'较少选择性',但我很好奇,如果sql服务器看到null,并知道在每种情况下这样使用左侧因为空语句。 我相信这是最好的做法,如下面的例子(如果你可以更好的查询下面请做!)但我只是好奇在这种情况下,为学习的目的,如果任何人都知道这里一致的内部行为。它适用于我所有的情况,但它也是一个主键,不可空,所以这可能是为什么这总是有效。如果它是一个可空类型,那么右边的可能会比左边的选择性更差,现在我们正在处理不同的情况。
我在这两个查询中的执行计划似乎是相同的。
反正 - 一个潜在的更好的方式来写这个(如果可以的话,请提高它)
declare @customerId int set @customerId = null select * from Customer where case when @customerId is null then 1 end = 1 or case when @customerId is not null then @customerId else -1 end = CustomerId
这里的想法是有动态SQL解决方法 - 所以我只是想确保我知道在所有情况下。
谢谢!
这似乎是一个类似的方法那篇文章工作得很好,不是吗? SELECT TOP 200 ... FROM customers WHERE(custno = @custno AND @custno IS NOT NULL) – 2011-04-27 04:01:08
@Adam - 这似乎没有做同样的事情?如果'@custno为空,它不会返回任何行。如果你的列是数字的,你可以使用'WHERE custno BETWEEN COALESCE(@custno,1)和COALESCE(@custno,2147483647)'(或者根据需要调整范围,如果不仅仅是正整数) – 2011-04-27 09:56:13
它的确切查询不是一回事 - 但在两种情况下,您都要比较两种情况下的客户ID = @(空),这在两种情况下都可能进行评估,因此在SQL服务器中允许这种情况非常相似,并且由于缺少短路而不会遇到问题 – 2011-04-27 17:46:24