zoukankan      html  css  js  c++  java
  • SQL 数据库引擎语句 sp_executesql 的使用介绍(Transact-SQL)

    SQL 数据库引擎语句 sp_executesql 的使用介绍(Transact-SQL)

    1、sp_executesql  介绍

    功能描述:执行可多次重用的Transact-SQL语句或批处理,或动态生成的语句或批处理。Transact-SQL语句或批处理可以包含嵌入参数。

    语法:

    -- SQL Server、Azure SQL数据库、Azure SQL数据仓库、并行数据仓库的语法
    sp_executesql [ @stmt = ] statement  
    [   
      { , [ @params = ] N'@parameter_name data_type [ OUT | OUTPUT ][ ,...n ]' }   
         { , [ @param1 = ] 'value1' [ ,...n ] }  
    ]  
    

    参数:

    [ @stmt= ] statement

    • 是包含Transact-SQL语句或批处理的Unicode字符串。@stmt必须是Unicode常量或Unicode变量。不允许使用更复杂的Unicode表达式,例如用+运算符连接两个字符串。不允许使用字符常量。如果指定了Unicode常量,则必须以N作为前缀。
    • 例如,Unicode常量 N'sp_who' 有效,但字符常量 'sp_who' 无效。字符串的大小仅受可用数据库服务器内存的限制。在64位服务器上,字符串的大小限制为2GB,即nvarchar的最大大小(max)。
    • 提示:@stmt可以包含与变量名格式相同的参数,例如:
    N'SELECT * FROM HumanResources.Employee WHERE EmployeeID = @IDParameter'

    [ @params= ] N'@parameter_name data_type [ ,... n ] '

    • 是一个字符串,它包含嵌入@stmt中的所有参数的定义。字符串必须是Unicode常量或Unicode变量。每个参数定义都由一个参数名和一个数据类型组成。n是表示其他参数定义的占位符。@stmt中指定的每个参数都必须在@params中定义。如果@stmt中的Transact-SQL语句或批处理不包含参数,则不需要@params。此参数的默认值为空。

    [ @param1= ] 'value1'

    • 参数字符串中定义的第一个参数的值。该值可以是Unicode常量或Unicode变量。必须为@stmt中包含的每个参数提供一个参数值。当@stmt中的Transact-SQL语句或批处理没有参数时,不需要这些值。

    [ OUT | OUTPUT ]

    • 指示参数是输出参数。text、ntext和image参数可以用作输出参数,除非该过程是公共语言运行时(CLR)过程。使用output关键字的输出参数可以是游标占位符,除非该过程是CLR过程。

    n

    • 是附加参数值的占位符。值只能是常量或变量。值不能是更复杂的表达式,如函数或使用运算符生成的表达式。

    返回值:

      0(成功)或非零(失败)

    2、sp_executesql  使用示例:

    2.1 sp_executesql支持与Transact-SQL字符串分开设置参数值,如下例所示。

    DECLARE @IntVariable INT;  
    DECLARE @SQLString NVARCHAR(500);  
    DECLARE @ParmDefinition NVARCHAR(500);  
      
    /* Build the SQL string one time.*/  
    SET @SQLString =  
         N'SELECT BusinessEntityID, NationalIDNumber, JobTitle, LoginID  
           FROM AdventureWorks2012.HumanResources.Employee   
           WHERE BusinessEntityID = @BusinessEntityID';  
    SET @ParmDefinition = N'@BusinessEntityID tinyint';  
    /*使用第一个参数值执行字符串。 */  
    SET @IntVariable = 197;  
    EXECUTE sp_executesql @SQLString, @ParmDefinition,  
                          @BusinessEntityID = @IntVariable;  
    /* 使用第二个参数值执行同一个字符串 */  
    SET @IntVariable = 109;  
    EXECUTE sp_executesql @SQLString, @ParmDefinition,  
                          @BusinessEntityID = @IntVariable;
    

      

    2.2 OUTPUT参数也可以与sp_executesql一起使用。以下示例从AdventureWorks2012检索职务。人力资源部。员工表并在输出参数@max_title中返回它。

    DECLARE @IntVariable INT;  
    DECLARE @SQLString NVARCHAR(500);  
    DECLARE @ParmDefinition NVARCHAR(500);  
    DECLARE @max_title VARCHAR(30);  
      
    SET @IntVariable = 197;  
    SET @SQLString = N'SELECT @max_titleOUT = max(JobTitle)   
       FROM AdventureWorks2012.HumanResources.Employee  
       WHERE BusinessEntityID = @level';  
    SET @ParmDefinition = N'@level TINYINT, @max_titleOUT VARCHAR(30) OUTPUT';  
      
    EXECUTE sp_executesql @SQLString, @ParmDefinition, @level = @IntVariable, @max_titleOUT=@max_title OUTPUT;  
    SELECT @max_title;
    

      

    2.3 下面的示例创建并执行一个简单的SELECT语句,该语句包含名为@level的嵌入参数。

    EXECUTE sp_executesql   
              N'SELECT * FROM AdventureWorks2012.HumanResources.Employee   
              WHERE BusinessEntityID = @level',  
              N'@level TINYINT',  
              @level = 109;
    

      

    2.4 下面的示例显示如何使用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)  
        )
    

    此示例存储过程动态生成并执行INSERT语句,以便将新订单插入正确的表中。该示例使用order date构建应包含数据的表的名称,然后将该名称合并到INSERT语句中。

    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个版本的插入字符串,每个月表一个版本。对于EXECUTE,每个插入字符串都是唯一的,因为参数值不同。尽管这两种方法生成的批处理数相同,但sp_executesql生成的插入字符串的相似性使得查询优化器更有可能重用执行计划。  

    2.5 下面的示例使用一个OUTPUT参数将SELECT语句生成的结果集存储在@SQLString中参数。然后使用输出参数的值执行SELECT语句。

    USE AdventureWorks2012;  
    GO  
    DECLARE @SQLString NVARCHAR(500);  
    DECLARE @ParmDefinition NVARCHAR(500);  
    DECLARE @SalesOrderNumber NVARCHAR(25);  
    DECLARE @IntVariable INT;  
    SET @SQLString = N'SELECT @SalesOrderOUT = MAX(SalesOrderNumber)  
        FROM Sales.SalesOrderHeader  
        WHERE CustomerID = @CustomerID';  
    SET @ParmDefinition = N'@CustomerID INT,  
        @SalesOrderOUT NVARCHAR(25) OUTPUT';  
    SET @IntVariable = 22276;  
    EXECUTE sp_executesql  
        @SQLString  
        ,@ParmDefinition  
        ,@CustomerID = @IntVariable  
        ,@SalesOrderOUT = @SalesOrderNumber OUTPUT;  
    -- This SELECT statement returns the value of the OUTPUT parameter.  
    SELECT @SalesOrderNumber;  
    -- This SELECT statement uses the value of the OUTPUT parameter in  
    -- the WHERE clause.  
    SELECT OrderDate, TotalDue  
    FROM Sales.SalesOrderHeader  
    WHERE SalesOrderNumber = @SalesOrderNumber;
    

      

    创建时间:2020.10.09  更新时间:

  • 相关阅读:
    【面积并】 Atlantis
    【动态前k大 贪心】 Gone Fishing
    【复杂枚举】 library
    【双端队列bfs 网格图建图】拯救大兵瑞恩
    【奇偶传递关系 边带权】 奇偶游戏
    【权值并查集】 supermarket
    CF w4d3 A. Pythagorean Theorem II
    CF w4d2 C. Purification
    CF w4d2 B. Road Construction
    CF w4d2 A. Cakeminator
  • 原文地址:https://www.cnblogs.com/guorongtao/p/13786941.html
Copyright © 2011-2022 走看看