这四句代码看不明白,请老师们讲讲,谢谢啊!
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参数的这种写法是什么意思呀,帮助也看了,不明白。
[解决办法]
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 = 35
B. 執行動態建立的字串
以下範例顯示使用 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, @PrmDeliveryDate
GO
在此程序中使用 sp_executesql 比使用 EXECUTE 來執行字串更有效率。使用 sp_executesql 時,只會產生 12 個版本的 INSERT 字串,每個月份資料表 1 個。使用 EXECUTE 時,每個 INSERT 字串都是唯一的,因為參數值不同。雖然二種方法都會產生相同數目的批次,但是 sp_executesql 產生的INSERT 字串之相似性可能會使查詢最佳化器重覆使用執行計劃。
另請參閱
批次
EXECUTE
於執行時期建立陳述式
系統預存程序
©1988-2000 Microsoft Corporation. All Rights Reserved.
[解决办法]
@a int output
表示此参数可以返回值
@a和@num必须成对出现,@num为返回变量
[解决办法]
declare @user varchar(1000)declare @moTable varchar(20)select @moTable = 'MT_10 'declare @sql nvarchar(4000) --定义变量,注意类型set @sql= 'select @user = count(distinct userid) from '+@moTable --为变量赋值--执行@sql中的语句exec sp_executesql @sql ,N '@user varchar(1000) out ' --表示@sql中的语句包含了一个输出参数 ,@user out --和调用存储过程差不多,指定输出参数值print @user