存储过程EXEC与sp_executesql的区别?

Reg*_*ser 27 sql sql-server stored-procedures sql-server-2008 sql-server-2012

我写了两个存储过程一个sp_executesql和其他没有sp_executesql都正确执行相同的结果,我没有得到这里有什么区别

EXEC(@SQL)vs EXEC sp_executesql @SQL,N'@ eStatus varchar(12)',@ eStatus = @Status

以及EXEC(@SQL)如何易于SQL注入和sp_executesql @SQL ......不是吗?

在没有sp_executesql的存储过程下面

ALTER proc USP_GetEmpByStatus
(
@Status varchar(12)
)
AS
BEGIN
DECLARE @TableName AS sysname = 'Employee'
Declare @Columns as sysname = '*'
DECLARE @SQL as nvarchar(128) = 'select ' + @Columns + ' from ' + @TableName + ' where Status=' + char(39) + @Status + char(39)
print (@SQL)
EXEC (@SQL)
END

EXEC USP_GetEmpByStatus 'Active'
Run Code Online (Sandbox Code Playgroud)

下面是sp_executesql的存储过程

create proc USP_GetEmpByStatusWithSpExcute
(
@Status varchar(12)
)
AS
BEGIN
DECLARE @TableName AS sysname = 'JProCo.dbo.Employee'
Declare @Columns as sysname = '*'
DECLARE @SQL as nvarchar(128) = 'select ' + @Columns + ' from ' + @TableName + ' where Status=' + char(39) + @Status + char(39)
print @SQL
exec sp_executesql @SQL, N'@eStatus varchar(12)', @eStatus = @Status
END

EXEC USP_GetEmpByStatusWithSpExcute 'Active'
Run Code Online (Sandbox Code Playgroud)

Joa*_*son 19

您的sp_executesql SQL可能应该是;

DECLARE @SQL as nvarchar(128) = 'select ' + @Columns + ' from ' + 
            @TableName + ' where Status=@eStatus'
Run Code Online (Sandbox Code Playgroud)

这将允许您使用@eStatus作为参数调用sp_executesql,而不是将其嵌入到SQL中.这样做的好处是@eStatus可以包含任何字符,如果需要安全,它将被数据库自动转义.

与EXEC所需的SQL相比;

DECLARE @SQL as nvarchar(128) = 'select ' + @Columns + ' from ' + 
            @TableName + ' where Status=' + char(39) + @Status + char(39)
Run Code Online (Sandbox Code Playgroud)

...嵌入在@Status中的char(39)会使您的SQL无效并可能创建SQL注入的可能性.例如,如果将@Status设置为O'Reilly,则生成的SQL将为;

select acol,bcol,ccol FROM myTable WHERE Status='O'Reilly'
Run Code Online (Sandbox Code Playgroud)


FLI*_*KER 19

除了用法之外,还有一些重要的区别:

  1. sp_executesql允许语句参数化因此它比EXECSQL注入更安全

  2. sp_executesql可以利用缓存的查询计划.TSQL字符串只构建一次,之后每次调用相同的查询时sp_executesql,SQL Server从缓存中检索查询计划并重新使用它

  3. 创建的EXEC临时表不能使用临时表缓存机制

  • 从https://blogs.msdn.microsoft.com/turgays/2013/09/17/exec-vs-sp_executesql/中删除 (4认同)