當需要根據外部輸入的參數來決定要執行的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類型,否則在執行的時候會報“過程需要類型為 'ntext/nchar/nvarchar' 的參數 '@statement'”的錯誤,如果是使用sp_executesql直接執行SQL語句,則必須在前面加上大寫字母N,以表明后面的字符串是使用Unicode類型編碼的。
下面來看看幾種動態執行SQL語句的情況
1.普通SQL語句
(1)exec('select * from Student')
(2)exec sp_executesql N'select * from Student'--此處一定要加上N,否則會報錯
2.帶參數的SQL語句
(1)declare @sql nvarchar(1000)
declare @userId varchar(100)
set @userId='0001'
set @sql='select * from Student where UserID='''+@userId+''''
exec(@sql)
(2)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類型的。
(3)帶輸出參數的SQL語句
create procedure sp_GetNameByUserId
(
@userId varchar(100),
@userName varchar(100) output
)
as
declare @sql nvarchar(1000)
set @sql=N'select @userName=UserName from Student where UserId=@userId'
exec sp_executesql N'@userId varchar(100),@userName varchar(100) output',@userId,@userName output
select @userName
鏈接:http://www.cnblogs.com/hnsdwhl/archive/2011/07/23/2114730.html