我意识到线程是旧的,但这里有一些额外的细节可能有助于作出适当的决定。有多种解决方案:
1)
SELECT ...
FROM ...
WHERE
(T.memberType = @memberType OR @memberType = -1)
AND (T.color = @color OR @color = -1)
AND (T.preference = @preference OR @preference = -1)
AND (T.groupNumber = @groupNumber OR @groupNumber = -1)
AND (T.departmentNumber = @departmentNumber OR @departmentNumber = -1)
2)
SELECT ...
FROM ...
WHERE
(T.memberType = @memberType OR @memberType IS NULL)
AND (T.color = @color OR @color IS NULL)
AND (T.preference = @preference OR @preference IS NULL)
AND (T.groupNumber = @groupNumber OR @groupNumber IS NULL)
AND (T.departmentNumber = @departmentNumber OR @departmentNumber IS NULL)
3)动态生成的DML和使用EXECUTE语句
4)动态生成的DML和使用sp_executesql的
选项1和2几乎是一样的......我会倾向于使用IS NULL而不是-1,但是与大多数情况一样,这取决于情况。这些选项的缺点之一是存储过程的第一次执行将产生一个查询计划,这个查询计划将在随后的所有调用中重用...随着参数值的变化(具体而言,您想忽略哪些),最初的查询计划可能不再是最佳计划......要解决此问题,请使用WITH RECOMPILE选项(注意每次调用该过程时都会重新编译该过程)。
随着向表中添加更多数据和/或将更多条件添加到WHERE子句中,选项3和4的性能会更好。但是,这些选项需要更多努力来编写存储过程,并需要对输入参数进行更多验证,以最大限度地减少潜在的SQL注入漏洞。选项4比选项3更好,从某种意义上讲更简单一些,因为动态生成的SQL包含参数名称,从而导致更有效的查询计划重用。动态生成的SQL的另一个缺点是调用存储过程的用户必须拥有对基础表/视图的所有必要权限,除非该过程是使用WITH EXECUTE AS ...子句定义的。
最后,我通常使用动态生成的SQL和sp_executesql来产生性能最好的查询。
这比使用'COALESCE'(对于NULL情况下)更快吗? – crush 2016-05-09 21:00:08