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 更新时间:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 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月简报