动态SQL-EXEC(@SQL)与EXEC SP_EXECUTESQL(@SQL)


95

使用SQL Server在存储过程中执行动态SQL命令的实际利弊是什么?

EXEC (@SQL)

EXEC SP_EXECUTESQL @SQL

Answers:


96

sp_executesql更有可能促进查询计划的重用。使用时sp_executesql,将在调用签名中显式标识参数。这篇优秀的文章描述了这一过程

关于动态SQL的许多方面,经常引用的参考资料是Erland Sommarskog的必读内容:“ 动态SQL的诅咒和祝福 ”。


21

SP_EXECUTESQL的重要之处在于,它允许您创建参数化查询,如果您关心SQL注入,那将非常好。


1
我不认为没有它,就无法对动态SQL进行参数化处理??
DJ。

EXEC('SELECT * FROM FOO WHERE ID =?',123)将替换参数占位符“?” 值123,然后执行查询,返回SELECT * FROM FOO WHERE ID = 123的结果
Peter Wone 2010年

1
糟糕,该语法仅适用于链接服务器。
Peter Wone 2010年

1
如果动态生成查询以防止sql注入,则绝对是使用sp_executesql的最大原因之一。
史蒂文·罗杰斯

5

Microsoft的《使用sp_executesql》一文建议使用sp_executesql代替execute语句。

因为此存储过程支持参数替换,所以sp_executesql比EXECUTE具有更多的用途;并且由于sp_executesql生成的执行计划更有可能被SQL Server重用,因此sp_executesql 比EXECUTE 更有效

所以,带走:不要使用executestatement。使用sp_executesql


7
您的外卖并不总是站得住脚的。有时候使用sp_executesql并没有效率的提高,但是您可以保护代码免受sql注入攻击。有时您只是不能像使用exec那样使用sp_executesql,所以...有人说-没有灵丹妙药。我同意。
OzrenTkalcecKrznaric 2013年

是的,微软应该把它作为“更可能是有效的”。在这个行业工作了几年,我看到了sp_executesql无法替代的情况execute。也许我应该强调的重点是:使用sp_executesql而不是execute 尽可能使用
2013年

2

这些天我会一直使用sp_executesql,实际上它只是EXEC的包装程序,用于处理参数和变量。

但是,当在非常大的数据库上优化查询时,不要忘记OPTION RECOMPILE,尤其是当您的数据跨多个数据库并且使用CONSTRAINT限制索引扫描时。

除非您使用OPTION RECOMPILE,否则SQL Server将尝试为查询创建“一刀切”的执行计划,并且每次运行时都将运行全索引扫描。

这比搜索效率低得多,这意味着它可能正在扫描整个索引,这些索引被限制在您甚至不查询的范围内:@


-2
  1. 声明变量
  2. 通过命令进行设置并添加动态部分,例如sp的使用参数值(此处@IsMonday和@IsTuesday是sp参数)
  3. 执行命令

    declare  @sql varchar (100)
    set @sql ='select * from #td1'
    
    if (@IsMonday+@IsTuesday !='')
    begin
    set @sql= @sql+' where PickupDay in ('''+@IsMonday+''','''+@IsTuesday+''' )'
    end
    exec( @sql)

15
如果您输入“ a'; DROP DATABASE DATABASE_NAME; GO;';”,则可以进行SQL注入。在@IsMonday变量中
Erik A. Brandstadmoen

如果@IsMonday是int,是否容易发生sql伤害?
维卡斯·拉纳

@VikasRana @IsMonday不能使用int动态SQL。需要注意的是@sql被声明为varcharnvarchar
卫辉郭
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.