declare @num int,@sqls nvarchar(4000)
set @sqls='select @a=count(*) from gzda'
exec sp_executesql @sqls,N'@a int output',@num output
select @num 我不明白的是 @a参数,@num参数的这种写法是什么意思呀,帮助也看了,不明白。
set @sqls='select @a=count(*) from gzda'
exec sp_executesql @sqls,N'@a int output',@num output
select @num 我不明白的是 @a参数,@num参数的这种写法是什么意思呀,帮助也看了,不明白。
Transact-SQL 程式語法的參考說明
sp_executesql
執行可以重新使用許多次或已經動態建立的 Transact-SQL 陳述式或批次。Transact-SQL 陳述式或批次可以包含內嵌參數。語法
sp_executesql [@stmt =] stmt
[
{, [@params =] N'@parameter_name data_type [,...n]' }
{, [@param1 =] 'value1' [,...n] }
]引數
[@stmt =] stmt包含 Transact-SQL 陳述式或批次的 Unicode 字串。stmt m 必須是 Unicode 常數或可以以隱含方式轉換為 ntext 的變數。更複雜的 Unicode 運算式是不允許的 (例如以 + 運算子串連二個字串),也不允許字元常數。如果指定常數,其前置字元必須是 N,例如,Unicode 常數 N’sp_who’ 是合法的,但字元常數 ‘sp_who’ 是不合法的。字串的大小僅受限於可用資料庫伺服器記憶體。stmt 可以包含與變數名稱相同形式的參數,例如:N'SELECT * FROM Employees WHERE EmployeeID = @IDParameter'stmt 中包括的每個參數必須在 @params 參數定義清單與參數值清單中都有對應的項目。[@params =] N'@parameter_name data_type [,...n]'包含嵌入 stmt 的所有參數之定義的字串。字串必須是 Unicode 常數或可以以隱含方式轉換為 ntext 的變數。每個參數定義包含一個參數名稱與資料型別。n 是指出額外參數定義的替代符號 (Placeholder)。stmt 中指定的每個參數都必須在 @params中定義。如果 stmt 中的 Transact-SQL 陳述式或批次不包含參數,就不需要 @params。參數的預設值為 NULL。[@param1 =] 'value1'參數字串中定義的第一個參數值。這個值可以是常數或變數。stmt 中包括的每個參數都必須有參數值。如果 stmt 中的 Transact-SQL 陳述式或批次沒有參數,就不需要參數值。n額外參數值的替代符號。值可以只是常數或變數。值不可以是函數或使用運算子建立的運算式等較複雜的運算式。傳回碼值
0 (成功) 或 1 (失敗)結果集
從內建在 SQL 字串的所有 SQL 陳述式傳回結果集。備註
在批次、名稱範圍與資料庫內容方面,sp_executesql 與 EXECUTE 的行為相同。直到執行 sp_executesql 陳述式之後,系統才會編譯 sp_executesql stmt 參數中的 Transact-SQL 陳述式與批次。系統接著編譯與執行 stmt 的內容,此執行計劃與呼叫 sp_executesql 的批次執行計劃分開執行。sp_executesql 批次無法參照呼叫 sp_executesql 的批次中宣告的變數。呼叫 sp_executesql 的批次看不到 sp_executesql批次中的區域指標或變數。資料庫內容的變更只會持續到 sp_executesql 陳述式的結尾。當陳述式中只變更參數值時,sp_executesql 可以用來替代預存程序來重覆執行 Transact-SQL 陳述式。因為 Transact-SQL 陳述式本身維持不變,只有參數值變更,Microsoft® SQL Server™ 查詢最佳化器可能會重覆使用第一次執行時產生的執行計劃。附註 如果陳述式字串中的物件名稱不完整,就不會重覆使用執行計劃。
sp_executesql 支援參數值與 Transact-SQL 字串分開設定:DECLARE @IntVariable INT
DECLARE @SQLString NVARCHAR(500)
DECLARE @ParmDefinition NVARCHAR(500)/* Build the SQL string once.*/
SET @SQLString =
N'SELECT * FROM pubs.dbo.employee WHERE job_lvl = @level'
SET @ParmDefinition = N'@level tinyint'
/* Execute the string with the first parameter value. */
SET @IntVariable = 35
EXECUTE sp_executesql @SQLString, @ParmDefinition,
@level = @IntVariable
/* Execute the same string with the second parameter value. */
SET @IntVariable = 32
EXECUTE sp_executesql @SQLString, @ParmDefinition,
@level = @IntVariable在 sp_executesql 中能變更參數的功能可以提供以下使用 EXECUTE 陳述式來執行字串的優點: 因為 sp_executesql 字串中 Transact-SQL 陳述式的實際文字在不同執行之間不會變更,查詢最佳化器可能會將第二次執行的 Transact-SQL 陳述式與第一次執行時產生的執行計劃比較。因此,SQL Server 不需要編譯第二個陳述式。
只建立一次 Transact-SQL 字串。
在其原生 (Native) 格式中指定整數參數。不需要轉換為 Unicode。
權限
執行權限預設授予 public 角色。範例
A. 執行簡單的 SELECT 陳述式
以下範例建立並執行一個簡單的 SELECT 陳述式,其中包含命名為 @level 的內嵌參數。execute sp_executesql
N'select * from pubs.dbo.employee where job_lvl = @level',
N'@level tinyint',
@level = 35B. 執行動態建立的字串
以下範例顯示使用 sp_executesql 來執行動態建立的字串。預存程序範例用來將資料插入分割年銷售資料的資料表集。以下為年度每個月資料表的格式:CREATE TABLE May1998Sales
(OrderID INT PRIMARY KEY,
CustomerID INT NOT NULL,
OrderDate DATETIME NULL
CHECK (DATEPART(yy, OrderDate) = 1998),
OrderMonth INT
CHECK (OrderMonth = 5),
DeliveryDate DATETIME NULL,
CHECK (DATEPART(mm, OrderDate) = OrderMonth)
)若需有關從資料分割的資料表擷取資料的詳細資訊,請參閱使用分割的檢視表。 每個資料表名稱包含月份名稱的前三個字母、年份的四位數字以及 Sales 常數。資料表名稱可以從訂單日期動態建立:/* Get the first three characters of the month name. */
SUBSTRING( DATENAME(mm, @PrmOrderDate), 1, 3) +
/* Concatenate the four-digit year; cast as character. */
CAST(DATEPART(yy, @PrmOrderDate) AS CHAR(4) ) +
/* Concatenate the constant 'Sales'. */
'Sales'此預存程序範例動態建立並執行 INSERT 陳述式,在正確的資料表中插入新訂單。預存程序使用訂單日期來建立應該包含資料的資料表名稱,然後將名稱併入 INSERT 陳述式。(這是 sp_executesql 的簡單範例。它不包含錯誤檢查,也不包括商業規則的檢查,例如確保不同資料表間的訂單號碼不會重複。)CREATE PROCEDURE InsertSales @PrmOrderID INT, @PrmCustomerID INT,
@PrmOrderDate DATETIME, @PrmDeliveryDate DATETIME
AS
DECLARE @InsertString NVARCHAR(500)
DECLARE @OrderMonth INT-- Build the INSERT statement.
SET @InsertString = 'INSERT INTO ' +
/* Build the name of the table. */
SUBSTRING( DATENAME(mm, @PrmOrderDate), 1, 3) +
CAST(DATEPART(yy, @PrmOrderDate) AS CHAR(4) ) +
'Sales' +
/* Build a VALUES clause. */
' VALUES (@InsOrderID, @InsCustID, @InsOrdDate,' +
' @InsOrdMonth, @InsDelDate)'/* Set the value to use for the order month because
functions are not allowed in the sp_executesql parameter
list. */
SET @OrderMonth = DATEPART(mm, @PrmOrderDate)EXEC sp_executesql @InsertString,
N'@InsOrderID INT, @InsCustID INT, @InsOrdDate DATETIME,
@InsOrdMonth INT, @InsDelDate DATETIME',
@PrmOrderID, @PrmCustomerID, @PrmOrderDate,
@OrderMonth, @PrmDeliveryDateGO在此程序中使用 sp_executesql 比使用 EXECUTE 來執行字串更有效率。使用 sp_executesql 時,只會產生 12 個版本的 INSERT 字串,每個月份資料表 1 個。使用 EXECUTE 時,每個 INSERT 字串都是唯一的,因為參數值不同。雖然二種方法都會產生相同數目的批次,但是 sp_executesql 產生的INSERT 字串之相似性可能會使查詢最佳化器重覆使用執行計劃。
另請參閱 批次EXECUTE於執行時期建立陳述式 系統預存程序©1988-2000 Microsoft Corporation. All Rights Reserved.
set @sqls='select @a=count(*) from gzda'
exec sp_executesql @sqls,N'@a int output',@num output
select @num
----------------------
谢,帮助我看了,不明白才问的,比如 为什么要写成@a int output,我改成input就不行呢?
还有:是不是两个参数必须成对出现才行呀,@a和@num必须成对出现。
表示此参数可以返回值@a和@num必须成对出现,@num为返回变量