Sof*_*ant 0 select stored-procedures where-clause sql-server-2008
我有一个包含多个列的表.我想要一个存储过程,如果这些值的参数不为null,将为每个值过滤Select*语句.我是否必须写一个像sql server字符串或其他什么,如果该参数不为null,只需将参数值附加到字符串?或者是否有一种更简单的内置机制用于此类事情?我知道你必须为Oracle做字符串事情.但ms sql server总是让我感到更加用户友好.在我进入鸽子之前,我想我会先检查一下.
谢谢
简单的路由,假设col不可为空,或者它是,并且您不希望NULL行匹配:
WHERE col LIKE COALESCE(@param, col)
-- or the longer version:
WHERE (col LIKE @param OR @param IS NULL)
Run Code Online (Sandbox Code Playgroud)
(凡@param要么NULL或者类似的东西'%asdf%'.)
如果可以col为空并且您确实希望NULL行匹配,则可以尝试:
WHERE COALESCE(col, 'x') LIKE COALESCE(@param, col, 'x')
Run Code Online (Sandbox Code Playgroud)
还有其他方法可以做到这一点,因为这可能会导致基于您的参数化设置的错误计划以及第一次缓存时使用的参数(由于"参数嗅探",这可能会导致计划选择不当),但是这可能在很大程度上与此无关,因为你的WHERE子句无论如何都要强制进行表格扫描.
当计划质量成为问题时,常见的替代方案是使用动态SQL,例如
DECLARE @sql NVARCHAR(MAX) = N'SELECT ... FROM ... WHERE 1 = 1';
IF @param IS NOT NULL
BEGIN
SET @sql += ' AND col LIKE ''' + REPLACE(@param, '''', '''''') + '%''';
END
Run Code Online (Sandbox Code Playgroud)
在这种情况下,确保optimize for ad hoc workloads启用该设置会很有帮助.
有关参数嗅探和动态SQL的信息,请参阅Erland Sommarskog的这些帖子:
http://www.sommarskog.se/query-plan-mysteries.html
http://www.sommarskog.se/dynamic_sql.html