使用exec和sp_executesql動態執行SQL語句(轉載)

當須要根據外部輸入的參數來決定要執行的SQL語句時,經常須要動態來構造SQL查詢語句,我的以爲用得比較多的地方就是分頁存儲過程和執行搜索查詢的SQL語句。一個比較通用的分頁存儲過程,可能須要傳入表名,字段,過濾條件,排序等參數,而對於搜索的話,可能要根據搜索條件判斷來動態執行SQL語句。

在SQL Server中有兩種方式來執行動態SQL語句,分別是exec和sp_executesql。sp_executesql相對而言具備更多的優勢,它提供了輸入輸出接口,能夠將輸入輸出變量直接傳遞到SQL語句中,而exec只能經過拼接的方式來實現。 還有一個優勢就是sp_executesql,可以重用執行計劃,這就大大提升了執行的性能。因此通常狀況下建議選擇sp_executesql來執行動態SQL語句。

使用sp_executesql須要注意的一點就是,它後面執行的SQL語句必須是Unicode編碼的字符串,因此在聲明存儲動態SQL語句的變量時必須聲明爲nvarchar類型(若是不知道SQL語句有多長,能夠直接用nvarchar(max)類型),不然在執行的時候會報「過程須要類型爲 'ntext/nchar/nvarchar' 的參數 '@statement'」的錯誤,若是是使用sp_executesql直接執行SQL語句,則必須在前面加上大寫字母N,以代表後面的字符串是使用Unicode類型編碼的。

下面來看看幾種動態執行SQL語句的狀況
 
1.普通SQL語句
exec('select * from Student') exec sp_executesql N'select * from Student'--此處必定要加上N,不然會報錯

 

2.帶參數的SQL語句html

declare @sql nvarchar(1000) declare @userId varchar(100) set @userId='0001'
set @sql='select * from Student where UserID='''+@userId+''''
exec(@sql)

 

declare @sql nvarchar(1000) declare @userId varchar(100) set @userId='0001'
set @sql=N'select * from Student where UserID=@userId'
exec sp_executesql @sql,N'@userId varchar(100)',@userId

從這個例子中能夠看出使用sp_executesql能夠直接將參數寫在sql語句中,而exec須要使用拼接的方式,這在必定程度上能夠防止SQL注入,所以sp_executesql擁有更高的安全性。另外須要注意的是,存儲sql語句的變量必須聲明爲nvarchar類型的。sql

 

3.帶輸出參數的SQL語句安全

create procedure [dbo].[sp_GetNameByUserId] ( @userId varchar(100), @userName varchar(100) output ) as
begin

    declare @sql nvarchar(1000) set @sql=N'select @userName=UserName from Student where UserId=@userId'
    exec sp_executesql @sql,N'@userId varchar(100),@userName varchar(100) output',@userId,@userName output select @userName

end

 

 

原文連接性能

相關文章
相關標籤/搜索