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;
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: sp_executesql是一个SQL Server系统存储过程,可以用于执行动态SQL语句并返回结果。它的语法如下: ``` sp_executesql [@stmt =] N'sql语句', [@params =] N'参数定义', [@param1 =] '值1', ... ``` 其中,@stmt是要执行的SQL语句,@params是一个可选的字符串,用于定义参数。参数定义是一个以逗号分隔的字符串列表,每个参数由其名称、数据类型和方向组成。如果SQL语句中包含参数占位符(例如@parameter_name),则必须在@params字符串中定义该参数。然后,可以在@stmt中使用参数占位符来引用这些参数。 例如,以下代码演示了如何使用sp_executesql执行动态SQL语句,其中包含一个参数占位符: ``` DECLARE @sql NVARCHAR(MAX) = N'SELECT * FROM my_table WHERE id = @id' DECLARE @id INT = 1 EXEC sp_executesql @sql, N'@id INT', @id ``` 在上面的示例中,@sql包含要执行的SQL语句,其中包含一个参数占位符@id。然后,使用sp_executesql执行该语句,并将参数@id传递给它。这将返回my_table表中id为1的行。 ### 回答2: sp_executesql是用于在SQL Server数据库中执行动态SQL语句的系统存储过程。它提供了一种安全、高效的方式来执行动态生成的SQL语句,可以将参数传递给动态SQL语句,以避免SQL注入攻击,并且可以在执行相同的SQL语句时重用执行计划,提高性能。 sp_executesql的基本语法如下: sp_executesql [@stmt =] N'sql语句', [@params =] N'参数定义', [@param1 =] 值1, [@param2 =] 值2, ... 其中,@stmt是动态SQL语句的字符串,@params是定义参数的字符串,参数定义使用@参数名和数据类型的形式。 通过使用sp_executesql,可以将参数传递给动态SQL语句,以避免SQL注入攻击。例如,可以在动态SQL语句使用参数@name来执行查询操作: DECLARE @name NVARCHAR(50) = N'John' DECLARE @sql NVARCHAR(1000) SET @sql = N'SELECT * FROM Customers WHERE CustomerName = @name' EXEC sp_executesql @sql, N'@name NVARCHAR(50)', @name 使用sp_executesql的另一个优点是,它可以在执行相同的SQL语句时重用执行计划,提高性能。例如,可以使用sp_executesql来执行一个频繁执行的动态SQL语句: DECLARE @sql NVARCHAR(1000) SET @sql = N'SELECT * FROM Orders WHERE OrderDate >= @startDate' EXEC sp_executesql @sql, N'@startDate DATETIME', '2022-01-01' EXEC sp_executesql @sql, N'@startDate DATETIME', '2022-02-01' 在执行第二个EXEC sp_executesql语句时,由于执行计划已经在第一个执行中生成,数据库引擎可以重用该计划,从而节省了资源和时间。 总之,sp_executesqlSQL Server数据库中的一个重要工具,可以安全、高效地执行动态SQL语句,并通过参数化和执行计划的重用提高性能。 ### 回答3: sp_executesql是一个存储过程,用于执行动态SQL语句。它可以接收动态生成的SQL语句以及参数列表作为输入,并执行这些语句。这个存储过程的语法如下: sp_executesql [@stmt =] N'sql语句', -- 需要执行的动态SQL语句 [@params =] N'参数定义列表', -- 参数列表的定义,包括参数的名称、数据类型和长度等信息 [@param1 =] '值1', -- 参数1 [@param2 =] '值2', -- 参数2 ... [@paramN =] '值N' -- 参数N 通过使用sp_executesql存储过程,我们可以在运行时动态生成SQL语句并将参数传递给它,从而实现更灵活的查询和操作数据库使用sp_executesql的好处之一是可以防止SQL注入攻击,因为参数是作为参数传递给SQL语句,而不是直接拼接到字符串中。 在使用sp_executesql时,我们首先需要提供要执行的动态SQL语句,并使用参数占位符(如@ParamName)来表示需要传递的参数。然后,我们可以定义参数列表,包括参数的名称、数据类型和长度等信息。最后,我们可以通过传递参数的值来执行动态SQL语句。 例如,假设我们需要根据传入的城市名称查询员工信息。我们可以使用sp_executesql执行以下动态SQL语句: DECLARE @city NVARCHAR(50) SET @city = '北京' DECLARE @sql NVARCHAR(1000) SET @sql = N'SELECT * FROM Employee WHERE City = @CityParam' EXEC sp_executesql @sql, N'@CityParam NVARCHAR(50)', @CityParam = @city 通过这种方式,我们可以根据传入的城市名称动态生成SQL语句,并将参数传递给它,从而实现根据不同的城市查询员工信息的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值