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

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

1、sp_executesql  介绍

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

语法:

1
2
3
4
5
6
-- 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可以包含与变量名格式相同的参数,例如:
1
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字符串分开设置参数值,如下例所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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中返回它。

1
2
3
4
5
6
7
8
9
10
11
12
13
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的嵌入参数。

1
2
3
4
5
EXECUTE sp_executesql  
          N'SELECT * FROM AdventureWorks2012.HumanResources.Employee  
          WHERE BusinessEntityID = @level'
          N'@level TINYINT'
          @level = 109;

  

2.4 下面的示例显示如何使用sp_executesql执行动态构建的字符串。示例存储过程用于将数据插入一组表中,这些表用于划分一年的销售数据。一年中每个月都有一个表格,其格式如下:

1
2
3
4
5
6
7
8
9
10
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语句中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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语句。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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  更新时间:

 

posted on   滔Roy  阅读(1564)  评论(0编辑  收藏  举报

编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报

导航

点击右上角即可分享
微信分享提示