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

本文详细介绍了SQL Server中的存储过程sp_executesql,包括其功能、语法、参数说明,并通过多个示例展示了如何动态执行Transact-SQL语句,使用输出参数以及在不同场景下的应用。sp_executesql能提高执行效率,尤其在处理动态SQL时。
摘要由CSDN通过智能技术生成

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;
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值