sp_executesql
執行可以多次重複使用或動態生成的 Transact-SQL 語句或批處理。Transact-SQL 語句或批處理可以包含嵌入引數。
Transact-SQL 語法約定
語法
sp_executesql [ @stmt = ] stmt |
備註
在批處理、名稱作用域和資料庫上下文方面,sp_executesql 與 EXECUTE 的行為相同。sp_executesql stmt 引數中的 Transact-SQL 語句或批處理在執行 sp_executesql 語句時才編譯。隨後,將編譯 stmt 中的內容,並將其作為執行計劃執行。該執行計劃獨立於名為 sp_executesql 的批處理的執行計劃。sp_executesql 批處理不能引用呼叫 sp_executesql 的批處理中宣告的變數。sp_executesql 批處理中的本地遊標或變數對呼叫 sp_executesql 的批處理是不可見的。對資料庫上下文所作的更改只在 sp_executesql 語句結束前有效。
如果只更改了語句中的引數值,則 sp_executesql 可用來代替儲存過程多次執行 Transact-SQL 語句。因為 Transact-SQL 語句本身保持不變,僅引數值發生變化,所以 SQL Server 查詢優化器可能重複使用首次執行時所生成的執行計劃。
注意: |
---|
如果語句字串中的物件名不是完全限定名,則該執行計劃不會被重複使用。 |
sp_executesql 支援與 Transact-SQL 字串分開的引數值的設定,如以下示例所示。
DECLARE @IntVariable int; |
輸出引數也可用於 sp_executesql。以下示例從 AdventureWorks.HumanResources.Employee 表中檢索名稱,並將其返回在輸出引數中。
DECLARE @IntVariable int; |
替換 sp_executesql 中的引數的能力,與使用 EXECUTE 語句執行字串相比,有下列優點:
- 因為在 sp_executesql 字串中,Transact-SQL 語句的實際文字在兩次執行之間並未改變,所以查詢優化器應該能將第二次執行中的 Transact-SQL 語句與第一次執行時生成的執行計劃匹配。因此,SQL Server 不必編譯第二條語句。
- Transact-SQL 字串只生成一次。
- 整數引數按其本身格式指定。不需要轉換為 Unicode。
引數
[ @stmt = ] stmt
包含 Transact-SQL 語句或批處理的 Unicode 字串。stmt 必須是可以隱式轉換為 ntext 的 Unicode 常量或變數。不允許使用更復雜的 Unicode 表示式(例如使用 + 運算子連線兩個字串)。不允許使用字元常量。如果指定常量,則必須使用 N 作為字首。例如,Unicode 常量 N'sp_who' 是有效的,但是字元常量 'sp_who' 則無效。字串的大小僅受可用資料庫伺服器記憶體限制。
注意: |
---|
在 64 位伺服器上,字串大小受 nvarchar(max) 大小的限制。 |
注意: |
---|
stmt 可以包含與變數名形式相同的引數,例如: N'SELECT * FROM HumanResources.Employee WHERE EmployeeID = @IDParameter' |
stmt 中包含的每個引數在 @params 引數定義列表和引數值列表中均必須有對應項。
[ @params = ] N'@parameter_name data_type [ ,... n ] '
包含 stmt 中嵌入的所有引數定義的字串。該字串必須是可隱式轉換為 ntext 的 Unicode 常量或變數。每個引數定義由引數名稱和資料型別組成。n 是表示附加引數定義的佔位符。在 stmt 中指定的每個引數必須在 @params 中定義。如果 stmt 中的 Transact-SQL 語句或批處理不包含引數,則不需要 @params。該引數的預設值為 NULL。
[ @param1 = ] 'value1'
引數字串中定義的第一個引數的值。該值可以是常量或變數。必須為 stmt 中包含的每個引數提供引數值。如果 stmt 中的 Transact-SQL 語句或批處理沒有引數,則不需要這些值。
OUTPUT
指示該引數是輸出引數。除非此過程是公共語言執行時 (CLR) 過程,否則 text、ntext 和 image 引數可用作 OUTPUT 引數。使用 OUTPUT 關鍵字的輸出引數可以為遊標佔位符,CLR 過程除外。
n
附加引數值的佔位符。這些值只能為常量或變數,不能是很複雜的表示式(例如函式)或使用運算子生成的表示式。
返回程式碼值
0(成功)或非零(失敗)
結果集
從生成 SQL 字串的所有 SQL 語句返回結果集。
許可權
要求具有 public 角色的成員身份。
示例
A. 執行簡單的 SELECT 語句
以下示例將建立並執行一個簡單的 SELECT 語句,其中包含名為 @level 的嵌入引數。
EXECUTE sp_executesql |
B. 執行動態生成的字串
以下示例顯示使用 sp_executesql 執行動態生成的字串。該示例中的儲存過程用於向一組表中插入資料,這些表用於劃分一年的銷售資料。一年中的每個月均有一個表,格式如下:
CREATE TABLE May1998Sales |
有關從這些分割槽表中檢索資料的詳細資訊,請參閱在分割槽檢視中修改資料。
每個表的名稱由月份名的前三個字母、年度的四位數字和常量 Sales 組成。表名可以從訂單日期動態生成。
/* Get the first three characters of the month name. */ |
此示例儲存過程將動態生成並執行 INSERT 語句,以便向正確的表中插入新訂單。此示例使用訂單日期生成應包含資料的表的名稱,然後將此名稱併入 INSERT 語句中。
注意: |
---|
這是一個簡單的 sp_executesql 示例。該示例不包含錯誤檢查以及業務規則檢查,如確保訂單號在各個表之間不重複。
|
CREATE PROCEDURE InsertSales @PrmOrderID INT, @PrmCustomerID INT, |
在該過程中使用 sp_executesql 比使用 EXECUTE 執行字串更有效。使用 sp_executesql 時,只生成 12 個版本的 INSERT 字串,每個月的表對應 1 個字串。使用 EXECUTE 時,因為引數值不同,每個 INSERT 字串均是唯一的。儘管兩種方法生成的批處理數相同,但因為 sp_executesql 生成的 INSERT 字串都相似,所以查詢優化器更有可能重複使用執行計劃。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16436858/viewspace-616630/,如需轉載,請註明出處,否則將追究法律責任。