SQL筛选器查询

我有一个包含许多字段的表。 我正在尝试在asp.net中创建搜索filter,以便用户可以通过一个或多个字段组合进行搜索。 所以基本上我想创建一个接受4个参数的单个存储过程,如果它不为空,它会将参数附加到WHERE子句……

TableExample有4列,Col1 Col2 Col3 Col4

我希望有一种方法可以使用单个存储过程来完成此操作,而不必为每个可能的组合创建一个。

我正在尝试这样的事情,这是不正确的,但它是迄今为止我所得到的。

谢谢!

CREATE PROCEDURE [dbo].[Search] @Col1 int, @Col2 int, @Col3 int, @Col4 int AS SET TRANSACTION ISOLATION LEVEL READ COMMITTED SELECT * FROM [dbo].[TestTable] WHERE 1=1 CASE WHEN @Col1 IN NOT NULL THEN AND [Col1] = @Col1 WHEN @Col2 IN NOT NULL THEN AND [Col2] = @Col2 WHEN @Col3 IN NOT NULL THEN AND [Col3] = @Col3 WHEN @Col4 IN NOT NULL THEN AND [Col4] = @Col4 END 

使用OR短路的事实。 我假设-1不是有效值。

 CREATE PROCEDURE [dbo].[Search] @Col1 int = -1, @Col2 int = -1, @Col3 int = -1, @Col4 int = -1 AS Begin SET TRANSACTION ISOLATION LEVEL READ COMMITTED SELECT * FROM [dbo].[TestTable] WHERE (@Col1 = -1 OR [Col1] = @Col1) and (@Col2 = -1 OR [Col2] = @Col2) and (@Col3 = -1 OR [Col3] = @Col3) and (@Col4 = -1 OR [Col4] = @Col4) END 

搜索是我使用动态sql或在代码中构建sql字符串的少见选项之一。 如果你有一个所有的sproc环境,请在你的sproc中使用动态sql。 对它进行参数化并使用sp_executeSQL来运行它以避免SQL注入

您可以使用与您拥有的方法类似的方法来执行此操作:

 WHERE CASE WHEN @Col1 IS NULL THEN true ELSE [Col1] = @Col1 END AND CASE WHEN @Col2 IS NULL THEN true ELSE [Col2] = @Col2 END ... 

或者你可以使它更简单,虽然可能不太可读:

 WHERE (@Col1 IS NULL OR [Col1] = @Col1]) AND (@Col2 IS NULL OR [Col2] = @Col2]) AND ... 

您必须使用动态SQL来执行此操作:

 CREATE PROCEDURE [dbo].[Search] @Col1 int, @Col2 int, @Col3 int, @Col4 int AS DECLARE @SQL nvarchar(MAX) SET TRANSACTION ISOLATION LEVEL READ COMMITTED SET @SQL = 'SELECT * FROM [dbo].[TestTable] WHERE 1=1 ' IF @Col1 IS NOT NULL SET @SQL = @SQL + ' AND Col1 = ''' + @Col1 + ''' ' IF @Col2 IS NOT NULL SET @SQL = @SQL + ' AND Col2 = ''' + @Col2 + ''' ' IF @Col3 IS NOT NULL SET @SQL = @SQL + ' AND Col3 = ''' + @Col3 + ''' ' IF @Col4 IS NOT NULL SET @SQL = @SQL + ' AND Col4 = ''' + @Col4 + ''' ' exec sp_executesql @SQL END 

请记住,这可能存在危险,包括SQL注入,以及可能出现的许多其他权限问题,因为它是动态SQL,但它是在数据库层中实现此目的的唯一方法。 如果要在应用程序层(在C#中)构建查询,则可以更彻底地防御SQL注入攻击。

一些动态SQL链接可能有助于您了解这些缺点:

http://www.sommarskog.se/dynamic_sql.html http://slashstar.com/blogs/tim/archive/2006/10/12/The-Prevalence-and-Dangers-of-SQL-Injection.aspx

谢谢大家的回复。 但是,我做的有点不同。 我希望它可以帮助别人! 这是我如何去做的:

 CREATE PROCEDURE [dbo].[TestTable_Search] @Col1 int, @Col2 uniqueidentifier, @Col3 datetime, @Col4 datetime AS SET TRANSACTION ISOLATION LEVEL READ COMMITTED SELECT * FROM [dbo].[TestTable] WHERE [Col1] = COALESCE(@Col1, Col1) AND [Col2] = COALESCE(@Col2, Col2) AND [Col3] >= COALESCE(@Col3 + "00:00:00", Col3) AND [Col4] <= COALESCE(@Col4 + "23:59:59", Col4)