在存储过程中构建动态SQL
目录
介绍
sp_executesql与EXECUTE命令
例1.0
例1.1
存储过程中的动态SQL
例2.0
在动态SQL中使用Like操作符,IN操作符和Order By
例3.0 - 使用LIKE操作符
例3.1 - 使用IN操作符
例3.2 - 使用Order By子句
结论
本文介绍如何在存储过程中构建和执行动态SQL。
介绍
在存储过程中的动态SQL是单个Transact-SQL语句或存储在变量中并使用SQL命令执行的一组语句。在SQL Server中可能有几种实现方法。本文将向您展示一种很好的方法。在详细解释之前,让我告诉你“何时使用动态SQL?” 我们不能肯定地说静态SQL将满足我们所有的编程需求。当我们需要根据不同的搜索参数检索一组记录时,需要动态SQL。比如说——员工搜索屏幕或通用报告,需要SELECT根据不同的WHERE子句执行不同的语句。
注意:最重要的是,变量中的动态SQL查询不会被编译、解析、检查错误,直到它们被执行。
sp_executesql与EXECUTE命令
可以使用EXECUTE命令或sp_executesql语句执行动态构建的Transact-SQL 语句。在这篇文章中我的示例里,我将使用sp_executesql,其更高效、执行更快并且还支持参数替换。如果我们使用EXECUTE命令来执行SQL String,那么所有参数都应该转换为字符,并在执行之前作为Query的一部分。但该sp_executesql声明提供了一种更好的实现方法。它允许我们将参数值替换为SQL String中指定的任何参数。在进入实际示例之前,让我用一个简单的例子来区分这两个命令。使用WHERE子句中的ID从employee表中选择一条记录。
使用EXECUTE命令的基本语法:
EXECUTE(@SQLStatement)
使用sp_executesql的基本语法:
sp_executesql [@SQLStatement],[@ParameterDefinitionList],
[@ParameterValueList]
例1.0
/* Using EXECUTE Command */
/* Build and Execute a Transact-SQL String with a single parameter value Using EXECUTE Command *//* Variable Declaration */
DECLARE @EmpID AS SMALLINT
DECLARE @SQLQuery AS NVARCHAR(500)
/* set the parameter value */
SET @EmpID = 1001
/* Build Transact-SQL String with parameter value */
SET @SQLQuery = 'SELECT * FROM tblEmployees WHERE EmployeeID = ' +
CAST(@EmpID AS NVARCHAR(10))
/* Execute Transact-SQL String */
EXECUTE(@SQLQuery)
在上面的示例1.0中,声明了两个变量。第一个变量@EmpID用作SQL查询的参数,第二个变量@SQLQuery用于构建SQL String。您可以清楚地看到变量@EmpID被强制转换为NVarchar 类型并作为SQL字符串的一部分。如果打印@SQLQuery字符串(PRINT @SQLQuery),您将获得实际的SQL查询,如下所示:
SELECT * FROM tblEmployees WHERE EmployeeID = 1001
最后,使用该EXECUTE命令执行上述查询 。
例1.1
/* Using sp_executesql */
/* Build and Execute a Transact-SQL String with a single parameter
value Using sp_executesql Command *//* Variable Declaration */
DECLARE @EmpID AS SMALLINT
DECLARE @SQLQuery AS NVARCHAR(500)
DECLARE @ParameterDefinition AS NVARCHAR(100)
/* set the parameter value */
SET @EmpID = 1001
/* Build Transact-SQL String by including the parameter */
SET @SQLQuery = 'SELECT * FROM tblEmployees WHERE EmployeeID = @EmpID'
/* Specify Parameter Format */
SET @ParameterDefinition = '@EmpID SMALLINT'
/* Execute Transact-SQL String */
EXECUTE sp_executesql @SQLQuery, @ParameterDefinition, @EmpID
在示例1.1中,声明了三个变量。该变量@EmpID用作SQL查询的参数,第二个变量@SQLQuery用于构建SQL字符串,第三个变量@ParameterDefinition用于在执行SQL字符串之前指定参数格式。如果您打印@SQLQuery字符串(PRINT @SQLQuery),您将获得如下所示的查询:
SELECT * FROM tblEmployees WHERE EmployeeID = @EmpID
在这个例子中,您可以清楚地看到该参数@EmpID包含在语句中。最后,sp_executesql获取必要的信息来执行参数替换并执行动态构建的SQL字符串。
- @SQLQuery - >包含SQL语句
- @ParameterDefinition - >包含参数定义
- @EmpID - >包含要替换为SQL语句中的参数的参数值。
注意:动态SQL字符串中包含的参数必须在“参数定义列表”和“参数值列表”中具有相应的条目。
存储过程中的动态SQL
本文的这一部分解释了一个真实的示例和示例过程“如何在存储过程中构建和执行动态SQL?”
例2.0
让我们举一个简单的例子——Employee表有普通字段,如EmployeeID,Name,Department,Designation,JoiningDate,Salary 和Description。您可以使用以下Transact-SQL CREATE TABLE语句在数据库中创建表Employee。
/* Transact-Sql to create the table tblEmployees */
CREATE TABLE tblEmployees
(EmployeeID SMALLINT IDENTITY(1001,1) NOT NULL,EmployeeName NVARCHAR(100) NOT NULL,Department NVARCHAR(50) NOT NULL,Designation NVARCHAR(50) NOT NULL,JoiningDate DATETIME NOT NULL,Salary DECIMAL(10,2) NOT NULL,[Description] NVARCHAR(1000) NULL
)
以下INSERT语句将一些示例记录插入tblEmployee 表中:
/* Transact SQL to insert some sample records into tblEmployee table */
INSERT INTO tblEmployees
(EmployeeName, Department, Designation, JoiningDate, Salary, [Description])
VALUES
('John Smith', 'IT Research', 'Research Analyst', '02/08/2005', 23000.00, 'Analyst since 2005')INSERT INTO tblEmployees
(EmployeeName, Department, Designation, JoiningDate, Salary, [Description])
VALUES
('John Micheal', 'IT Operations', 'Manager', '07/15/2007', 15000.00, NULL)INSERT INTO tblEmployees
(EmployeeName, Department, Designation, JoiningDate, Salary, [Description])
VALUES
('Will Smith', 'IT Support', 'Manager', '05/20/2006', 13000.00, 'Joined last year as IT Support Manager')
我们的程序员可能会获得开发Employee搜索屏幕或生成Employee列表报告的任务,该报告将搜索数据库并根据搜索条件返回结果。在这种情况下,搜索界面应足够灵活,以便在数据库中搜索所有可能的标准。用户可能需要搜索以下详细信息:
- 使用Name搜索特定的Employee明细
- 在特定Department中的Employee列表
- 在特定Designation中的 Employee列表
- 去年加入该组织的Employee列表
- Employees Salary > =某些特定金额的s 列表
- 上面列出的任何这些条件或所有这些条件
我在这里列出了一些可能的条件。可能还有许多其他可能性完全取决于用户要求。这里让我们列出几个可能的标准,并编写一个构建动态SQL的存储过程,它将用于搜索Employee表中的详细信息。以下CREATE PROCEDURE语句将创建一个存储过程“sp_EmployeeSelect”,其中包含必要的输入参数和变量以构建动态SQL。
/* This stored procedure builds dynamic SQL and executes
using sp_executesql */
Create Procedure sp_EmployeeSelect/* Input Parameters */@EmployeeName NVarchar(100),@Department NVarchar(50),@Designation NVarchar(50),@StartDate DateTime,@EndDate DateTime,@Salary Decimal(10,2)ASSet NoCount ON/* Variable Declaration */Declare @SQLQuery AS NVarchar(4000)Declare @ParamDefinition AS NVarchar(2000) /* Build the Transact-SQL String with the input parameters */ Set @SQLQuery = 'Select * From tblEmployees where (1=1) ' /* check for the condition and build the WHERE clause accordingly */If @EmployeeName Is Not Null Set @SQLQuery = @SQLQuery + ' And (EmployeeName = @EmployeeName)'If @Department Is Not NullSet @SQLQuery = @SQLQuery + ' And (Department = @Department)' If @Designation Is Not NullSet @SQLQuery = @SQLQuery + ' And (Designation = @Designation)'If @Salary Is Not NullSet @SQLQuery = @SQLQuery + ' And (Salary >= @Salary)'If (@StartDate Is Not Null) AND (@EndDate Is Not Null)Set @SQLQuery = @SQLQuery + ' And (JoiningDate BETWEEN @StartDate AND @EndDate)'/* Specify Parameter Format for all input parameters included in the stmt */Set @ParamDefinition = ' @EmployeeName NVarchar(100),@Department NVarchar(50),@Designation NVarchar(50),@StartDate DateTime,@EndDate DateTime,@Salary Decimal(10,2)'/* Execute the Transact-SQL String with all parameter value's Using sp_executesql Command */Execute sp_Executesql @SQLQuery, @ParamDefinition, @EmployeeName, @Department, @Designation, @StartDate, @EndDate,@SalaryIf @@ERROR <> 0 GoTo ErrorHandlerSet NoCount OFFReturn(0)ErrorHandler:Return(@@ERROR)
GO
此示例存储过程将少量参数作为输入,并使用两个变量来构建和执行。@SQLQuery用于构建动态SQL语句。@ParamDefinition用于定义参数的格式。在每个步骤中构建SQL字符串时,使用IF-statement来检查输入的参数是否为Null。如果不是NULL,则该参数将包含在SQL语句中,该语句基本上在SQL语句的WHERE 子句中添加条件。您可以在过程中清楚地看到变量@ParamDefinition包含所有参数列表,最后使用sp_Executesql得到SQL-query、参数列表和参数值来执行SELECT语句。
让我们考虑一下上面列出的一些标准,看看这个存储过程是如何工作的。
- Employee使用名称搜索特定详细信息。
/* 1. Search for specific Employee Detail with the Name say 'John Smith'. */
EXEC sp_EmployeeSelect 'John Smith', NULL, NULL, NULL, NULL, NULL
执行上述语句将列出Employee “ John Smith” 的详细信息。
- 在特定的Department中的Employee列表,和
- 在特定的Designation中Employee列表。
/* 2. List of Employees in a specific Department. AND
3. List of Employees in a specific Designation. */
/* Say Department = 'IT Operations' AND Designation = 'Manager'*/
EXEC sp_EmployeeSelect NULL, 'IT Operations', 'Manager', NULL, NULL, NULL
执行上述声明将列出在IT运营部门中的Manager的详细信息。
在动态SQL中使用Like操作符,IN操作符和Order By
当我们构建动态SQL时,可能会有一些我们需要使用LIKE操作符,IN操作符和Order BY子句的实例。但是这些操作符和Order By子句使用的参数不像通常在使用sp_executesql对“ =”和“Between”操作符时那样工作。通常sp_executesql不会对order by子句执行参数替换,这样做会导致列引用问题。直接使用LIKE操作符和IN操作符会导致语法错误,当我们将参数包含在动态SQL语句中时,无法纠正。可以通过在动态SQL语句中包含实际参数值来解决此问题。以下示例显示在使用sp_executesql时如何使用Like操作符、IN操作符和OrderBy子句。
例3.0 - 使用LIKE操作符
例3.0使用LIKE操作符选择Employee名称为'John
'的列表。在此示例中,参数不包含在SQL语句中,而是将参数的实际值添加到SQL语句中。所以在这里,不需要参数定义来执行SQL字符串。这同样适用于下面显示的其他两个例子:
/* Variable Declaration */
DECLARE @EmpName AS NVARCHAR(50)
DECLARE @SQLQuery AS NVARCHAR(500)/* Build and Execute a Transact-SQL String with a single parameter
value Using sp_executesql Command */
SET @EmpName = 'John'
SET @SQLQuery = 'SELECT * FROM tblEmployees
WHERE EmployeeName LIKE '''+ '%' + @EmpName + '%' + ''''
EXECUTE sp_executesql @SQLQuery
例3.1 - 使用IN操作符
Example 3.1使用IN操作符选择Employee细节(ID = 1001,1003):
/* Variable Declaration */
DECLARE @EmpID AS NVARCHAR(50)
DECLARE @SQLQuery AS NVARCHAR(500)/* Build and Execute a Transact-SQL String with a single
parameter value Using sp_executesql Command */
SET @EmpID = '1001,1003'
SET @SQLQuery = 'SELECT * FROM tblEmployees
WHERE EmployeeID IN(' + @EmpID + ')'
EXECUTE sp_executesql @SQLQuery
例3.2 - 使用Order By子句
例3.2 Employee 按“ Department”列对记录进行排序。
/* Variable Declaration */
DECLARE @OrderBy AS NVARCHAR(50)
DECLARE @SQLQuery AS NVARCHAR(500)/* Build and Execute a Transact-SQL String with a single parameter
value Using sp_executesql Command */
SET @OrderBy = 'Department'
SET @SQLQuery = 'SELECT * FROM tblEmployees Order By ' + @OrderByEXECUTE sp_executesql @SQLQuery
结论
在本文中,我已经用几个例子对“如何在存储过程中构建和执行动态SQL”进行了解释。希望本文能够以一种友好的方式帮助您理解和编写动态SQL。
原文地址:https://www.codeproject.com/Articles/20815/Building-Dynamic-SQL-In-a-Stored-Procedure
在存储过程中构建动态SQL相关推荐
- 存储过程中执行动态Sql语句
MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...
- mysql 存储过程 表名_MySql存储过程中执行动态SQL(表名是变量)
项目中要显示每个表的记录条数,但是因为数据库中的索引表中(infomation_schema.tables)记录的每个表的数据条数不是那么实时(超过3w多就不准了),所以要手动持久化一下再显示,持久化 ...
- DB2 存储过程中执行动态SQL的两种写法
样本代码: DROP PROCEDURE QUOTATION.COPY_SAMPLE; CREATE PROCEDURE QUOTATION.COPY_SAMPLE (IN tableNameFrom ...
- oracle中执行动态sql语句吗,oracle中有没有可动态执行sql语句的函数
oracle中有没有可动态执行sql语句的函数 关注:233 答案:2 手机版 解决时间 2021-03-05 15:53 提问者祗剩寂寞 2021-03-04 22:38 oracle中有没有可 ...
- SQL Server中的动态SQL
In this article, we will review how to construct and execute dynamic SQL statements in SQL Server wi ...
- 在Oracle中执行动态SQL的几种方法------转载
在Oracle中执行动态SQL的几种方法 在一般的sql操作中,sql语句基本上都是固定的,如: SELECT t.empno,t.ename FROM scott.emp t WHERE t.de ...
- Oracle 存储过程,Hibernate 调用存储过程,JDBC调用存储过程,Oracle 动态SQL
Oracle 存储过程学习 目录 Oracle 存储过程........................................................................ ...
- oracle 动态执行ddl语句,Oracle过程中执行动态SQL或DDL语句
如果你用的是 Oracle 8i 及以上的版本,那简单,在过程中用 execute immediate sql_str 就行, sql_str 是一个拼凑的 SQL 语句, 如果你用的是 Oracle ...
- mybatis中mapper文件中的动态sql语句
有时候在检索时,用户提供的数据不一样多,我们很难使用静态的sql语句进行判别,所以这个时候需要使用动态的sql语句 这里主要针对Mapper.xml文件中的sql语句,笔者在下面所有的例子中只提供了M ...
最新文章
- python 判断字典是否包含某个key,以及对应的value 值
- ios手机连接远程服务器,04-iOS逆向工程使用SSH通过USB远程登录越狱iPhone
- 神经科学中的数学之美
- * Linux相关命令
- Lucene学习总结之六:Lucene打分公式的数学推导
- 在c语言中,字符串topt65的长度是,谭浩强c__程序设计第13章.ppt
- spring异常处理实例(登录例子)
- plsql配置连接远程数据库
- 计算机备份记录陶瓷厂,陶瓷企业管理软件生产系统历史数据归档 | 了得信息技术...
- AngularJS的学习--ng-show/ng-hide/ng-if和ng-switch
- WebForm中 页面传参的总结
- destoon短信接口更换成和其他运营商通道并存
- 【资料合集】阿里巴巴开源技术汇总——内含115个软件与100+技术文档、PDF下载
- Spring-boot-2.1.X源码编译
- js仿百度文库文档上传页面的分类选择器_第二版
- 【学习笔记】多目标优化问题分解成若干简单多目标子问题--MOEA/D-M2M
- 使用Qt构建ROS应用程序
- java频繁的读写文件_大量较为频繁读写的文件一般如何进行存储?
- oralc UPDATE关联表的思路总结
- Federico Ferrari 和Ole Sigmund的高效3D拓扑优化程序
热门文章
- mysql文件导出NULL值处理_Mysql select into outfile NULL值导出的处理方法
- php中浮点数四舍五入,php浮点数四舍五入函数
- 为什么要用shiro框架_社群裂变为什么要用微信群助手?怎么去策划社群的线上裂变?...
- UI设计动效\动画素材模板|分层分步骤学习动效设计
- Inject Dll 过程
- datatable转list方法(有借鉴到他人)
- OpenAirInterface中的哈希表hashtable实现
- 用户需求说明书_「软件项目管理入门」(21) 需求调研和需求分析怎么做?
- centos升级内核 大漠知秋_记一次centos 7内核升级事故
- linux 下 qserialport waitforreadyread_北师大版初中数学八年级(下)第二章第一节不等关系(精品)...