我需要编写一个搜索查询(存储过程),其中输入参数的数量将超过 15 个。用户可以传递单个参数值或参数组合。
最好的方法是什么
静态方法如下:
DECLARE @FirstName VARCHAR(50) = 'XYZ' , @LastName VARCHAR(50) = 'ABC' , @MiddleName VARCHAR(50) = '999-9999%''; Select 1 as Abc where 1 like ''%1' SELECT * FROM [Person].[Person] WHERE FirstName LIKE '%' + @FirstName + '%' OR LastName LIKE '%' + @LastName + '%' OR MiddleName LIKE '%' + @MiddleName + '%'
动态 SQL 方法如下:
DECLARE @FirstName VARCHAR(50) = 'XYZ', @LastName VARCHAR(50) = 'ABC', @MiddleName VARCHAR(50) = '999-9999%' DECLARE @select VARCHAR(5000) = 'Select * from [Person].[Person] ' DECLARE @WhereClause VARCHAR(5000) = 'Where' IF (@FirstName IS NOT NULL OR @FirstName <> '') SET @WhereClause = @WhereClause + ' FirstName Like ''%' + @FirstName + '%''' IF (@LastName IS NOT NULL OR @LastName<> '') IF (@WhereClause <> 'Where') SET @WhereClause = @WhereClause + ' OR LastName Like ''%' + @LastName+ '%''' ELSE SET @WhereClause = @WhereClause + ' LastName Like ''%' + @LastName+ '%''' IF (@MiddleName IS NOT NULL OR @MiddleName <> '') IF (@WhereClause <> 'Where') SET @WhereClause = @WhereClause + ' OR MiddleName Like ''%' + @MiddleName + '%''' ELSE SET @WhereClause = @WhereClause + ' MiddleNameLike ''%' + @MiddleName + '%'''
exec(@select + @WhereClause)
现在的问题:
使用方法 1 时,我必须在 WHERE
子句中包含每个参数。我认为这会导致性能下降,每次即使未提供参数值,它仍会在相关列中搜索。
对于方法2我认为很可能是SQL Injection。 例子: 如果情况 2 中的参数值作为
传递DECLARE @FirstName VARCHAR(50) = 'XYZ', @LastName VARCHAR(50) = 'ABC', @MiddleName VARCHAR(50) = '999-9999%''; Select 1 as Abc where 1 like ''%1';
将执行的 SQL 查询结果为
Select * from [Person].[Person] Where FirstName Like '%XYZ%' OR LastName Like '%ABC%' OR MiddleName Like '%999-9999%'; Select 1 as Abc where 1 like '%1%'
这不好。
那么以最佳性能进行编码的最佳方法是什么。
最佳答案
我更喜欢方法#1。
- 更容易维护 #1 中的代码。
- 在大多数情况下,#1 会比 #2 快。
- 处理引号内的引号是一件令人头疼的事情。
' 或姓氏,如 ''%' + @LastName+ '%'''
- 动态 SQL 更难调试。可能不是这种情况。
- 当您的需求发生变化时,您的动态代码将变得更加困惑 梅西耶。
- 查询计划不会缓存在 #2 中。
- SQL 注入(inject)如您所述。
关于t-sql - 搜索查询动态与静态 - SQL Server 2012,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22701331/