Tsql 搜索查询动态与静态-SQL Server 2012
我需要编写一个搜索查询(存储过程),其中输入参数的数量将超过15个。用户可以传递单个参数值或参数组合 最好的方法是什么Tsql 搜索查询动态与静态-SQL Server 2012,tsql,sql-server-2012,sql-injection,dynamic-sql,Tsql,Sql Server 2012,Sql Injection,Dynamic Sql,我需要编写一个搜索查询(存储过程),其中输入参数的数量将超过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]
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 + '%'
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 + '%'''
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 + '%'
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 + '%'''
将执行的结果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'的LastName+ “%”
- 动态sql更难调试。在这种情况下可能不是这样李>
- 当您的需求发生变化时,您的动态代码将变得更加混乱和复杂 梅西耶李>
- 查询计划不会缓存在#2中
- SQL注入如您所示
- 动态SQL通常会受到性能影响,因为它无法在SQL server中缓存查询计划
我个人也喜欢方法1,但如果做得不好,那么它可能会非常慢,特别是因为像变量“%text%”这样的开放式语句可能需要大量时间来执行
我的建议是让输入参数的默认值为null,然后按如下方式构造WHERE子句
这意味着在未提供参数的实例中,它只返回所有其他匹配结果SELECT * FROM table t WHERE t.column1 = ISNULL(@param1, t.column1) AND t.column2 = ISNULL(@param2, t.column2)
对于日期范围匹配,您可能需要做一些聪明的事情,但是,如果参数为NULL,则使用最小和最大可能的日期/时间,以确保所有记录都应在该范围内。如果
为NULL,请避免使用t.column1
,在这种情况下,即使在t.column1=ISNULL(@param1,t.column1)
上找到匹配项,也会忽略该行。对于这种情况,我认为将t.column2
更改为和
可能有效。或