2017-04-03 62 views
1

我一直在使用动态查询在SQL服务器一样了:sp_executesql的使用总是真实情况

declare @sql nvarchar (1000),@condition nvarchar(100)=''; 
set @sql=N'select * from tablename where (0=0)'[email protected]+''; 
exec(@sql) 

这个我能得到我的结果@condition是否有任何价值或不是。 但是我知道sp_executesqlexec更好,因为它促进了查询计划的重用。

所以,我想我的`sp_executesql的查询,

set @sql =N'select * from dbo.testclient where (0=0) @condition' 
exec sp_executesql @sql,N'@condition nvarchar(100)',@condition 

,但它因错误而失败的

Incorrect syntax near '@condition'. 

我的问题是如何才能让上面的查询与sp_executesql在哪里工作参数@condition可以是一个条件或空白(''),我做错了什么。

+0

动态SQL是有风险的。也许你应该尝试找出一种方法,在没有它的情况下得到你想要的东西。 –

+1

这仍然是一个开放的SQL注入攻击。如果用户输入条件'column ='value'; drop table tablename;'',你认为会发生什么? –

+0

@Zohar首先感谢指出这个问题,我们务实地为查询创建参数,第二我只是想避免写多个条件来获得相同的结果。 – vikscool

回答

0

当您在sp_executesql中使用@condition之类的变量时,它不会简单地将sql字符串中的变量替换为变量的内容。

会发生什么情况是该变量绑定到提供的值并且sql语句未触及。

这一切意味着如果您想要利用查询计划重用,则需要创建一个使用变量的完整sql语句。

例如:

SET @byIDsql = 'select * from tableName where (0=0) and Id = @Id' 
SET @byNameSQL = 'select * from tableName where (0=0) and FirstName = @FirstName' 

然后你就可以使用sp_executesql的供应@id和@firstName的价值,并得到重用查询计划。

exec sp_executesql @byIDsql, N'@ID INT', 15 
+0

我实际上是在试图避免写多个查询。 – vikscool

+0

是的,这是一个麻烦。您仍然可以生成查询,但确实需要更多工作。如果你想保持sql注入的安全性和/或想要最大化查询计划的重用,那么工作很难解决。 –

+0

我强烈推荐阅读Erland Sommarskog发布的这篇博客文章http://www.sommarskog.se/dynamic_sql.html –

0

测试的代码,

 DECLARE @Sql nvarchar(MAX)='',         
     @paramlist nvarchar(4000),   
@id int=3 
set @paramlist = N' @id1 int' 
set @Sql='select * from test where [email protected]' 

exec sp_executesql @Sql,@paramlist,@id 
select @Sql 
+0

@PeterHenell,我只给出了sp_executesql的语法,而没有测试执行plan.query计划可能不会被重复用于不同的拉森。现在检查我的脚本。 – KumarHarsh

+0

@PeterHenell,现在检查 – KumarHarsh

+0

是的,多数民众赞成在做的方式。 –

相关问题