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参数的这种写法是什么意思呀,帮助也看了,不明白。

解决方案 »

  1.   


    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.
      

  2.   

    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 int output,我改成input就不行呢?
    还有:是不是两个参数必须成对出现才行呀,@a和@num必须成对出现。
      

  3.   

    @a int output
    表示此参数可以返回值@a和@num必须成对出现,@num为返回变量
      

  4.   

    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