SQL存储过程动态SQL执行技巧:EXEC与sp_executesql比较

创始人
2024-12-16 07:06:29
0 次浏览
0 评论

怎样SQL存储过程中执行动态SQL语句

执行动态Sql语句在存储过程中,MSSQL提供了两个命令来动态执行SQL语句;EXEC和sp_executesql;通常sp_executesql提供输入和输出接口;没有执行。
另一个最大的好处是使用sp_executesql允许您重用执行计划;这极大地提高了执行性能并允许您编写安全的代码。
EXEC在某些情况下可以更加灵活。
除非您有充分的理由使用EXEC。
尝试使用sp_executesql.1有两种方法使用EXEC命令;一种是运行存储过程,另一种是运行动态批处理过程。
第二种用法如下。
然后使用EXEC显示示例代码1代码DECLARE@TableNameVARCHAR(50),@SqlNVARCHAR(MAX),@OrderIDINT;SET@TableName='Orders';SET@OrderID=10251;SET@sql='SELECT*FROM'+QUOTENAME(@TableName)+'WHEREOrderID='+CAST(@OrderIDASVARCHAR(10))+'ORDERBYORDERIDDESC'EXEC(@sql)注意:尽管此处EXEC括号中只允许使用单个字符串变量。
如果我们像这样编写EXECEXEC('SELECTTOP('+CAST(@TopCountASVARCHAR(10))+')*FROM'+)+。
'ORDERBYORDERIDDESC');SQL编译器会报错,编译不会跳过:EXEC(@sql+@sql2+@sql3);多变的然后用这个变量作为EXEC命令的输入参数;只有这样才不会受到限制。
EXEC的缺点是不提供接口无法执行包含变量符号的批处理。
@TableName='Orders';SET@OrderID=10251;SET@sql='SELECT*FROM'+QUOTENAME(@TableName)+'WHEREOrderID=@OrderIDORDERBYORDERIDDESC'EXEC(@sql);KEY位于SET@sql语句中,如果我们运行这个批次,来自编译器的错误Msg137;15级,它将在State2、Line1中发行。
声明标量变量“@OrderID”。
使用EXEC时如果你想访问一个变量;您必须将变量内容组合成一行动态构造的代码,例如SET@sql='SELECT*FROM'+QUOTENAME(@TableName)+'WHEREOrderID='+CAST。
(@OrderIDASVARCHAR(10))+'ORDERBYORDERIDDESC'关系变量的内容也存在性能缺点。
SQLServer为每个查询字符串创建一个新的执行计划。
查询模式是相同的。
为了证明这一点,首先清除缓存中的DBCCFREEPROCCACHE执行计划(本文不涉及,可以查看MSDN代码1三遍,设置以下三个值为@OrderID,10251,10252,10253。
然后SELECTcacheobjtype,objtype,usecounts,按F5查询sqlFROMsys.sqlNOTLIKE动态批处理也不支持输出参数返回例如下面的代码返回订单表中所有记录的条数。
DECLARE@sqlNVARCHAR='SELECTCOUNT(@sql);但是,如果要返回调用批处理的输出,则必须使用INSERTEXEC语法将输出插入到目标表中;然后从表中获取值并将其分配给一个变量,如下所示:代码DECLARE@sqlNVARCHAR(MAX),@RecordCountINTSET@sql='SELECTCOUNT(OrderID)FromOrders';CREATETABLE#T(TIDINT);INSERTINTO#TEXEC(@sql);SET@RecordCount=(SELECTTIDFROM#T)SELECT@RecordCountDROPTABLE#T22使用sp_executesqlsp_executesql命令的执行晚于SQLServer中的EXEC命令。
推出来,主要是为回收提供更好的支持。

为了与EXEC进行尖锐的比较,让我们看看是否使用代码1中的代码将EXEC替换为sp_executesql以获得所需的结果代码DECLARE@TableNameVARCHAR(50),@sqlNVARCHAR(MAX),@OrderIDINT,@sql2NVARCHAR(MAX);SET@TableName='订单';SET@OrderID=10251;SET@sql='SELECT*FROM'+QUOTENAME(@TableName)+'WHEREOrderID='+CAST(@OrderIDASVARCHAR(50))+'ORDERBYORDERIDDESC'EXECsp_executesql@sql关注最后一行;sp_executesql更灵活,因为它提供了一个接口。
它提供了一个接口,提供输入参数,也提供输出参数。
此功能允许您创建带有约束的查询字符串,以便sp_executesql的结构比executesql具有更好的可重用性,除非您是动态构建代码。
这包括:代码阻塞;由限制声明部分和限制设置部分组成。
经过一番交谈后,我们看一下它的语法:EXECsp_executesql@stmt=,--类似存储过程body@params=,--存储过程参数部分;声明的参数类型--同理当调用存储过程时;为参数赋值参数值可以将一个参数的值赋给另一个参数。
@stmt参数是动态批量输入;可以引入输入参数或输出参数;它与存储过程的主语句相同,只是它是动态的。
sp_executesql;@params参数类似于指定输入/输出参数的存储过程标头,实际上存储过程标头@类似于调用的EXEC部分。
存储过程。
实际上,@stmt和@params是可选的;execsp_executesql的语法可以缩写为以下格式:EXECsp_executesql,,例如,sp_executesql优于executesql的执行计划,后者将使用前面讨论的EXEC代码。
代码DECLARE@TableNameVARCHAR(50),@sqlNVARCHAR(MAX),@OrderIDINT;SET@TableName='订单';SET@OrderID=10251;SET@sql='SELECT*FROM'+@TableName+'WHEREOrderID=@OIDORDERBY'ORDERID;-当你想限制动态sql语句的表名时。
请注意,不能指定以下内容:--set@sql='select*from@TableNamewhereOrderID=@OIDORDERBYOrderiddesc';--如果它提示您申报。
标量变量@TableName;只能使用@TableName作为变量名来拼接上面写的EXECsp_execut。
esql@sql,N'@OIDint',@OID=@OrderID在调用execsp_executesql代码并检查其生成的执行计划之前;缓存中的处理计划清除它。
DBCCFREEPROCCACHE执行上述动态代码3次;每个函数都会为@OrderID分配不同的值,查询sys.syscacheobjects表,并集中其输出。
优化器只创建了一个替代程序,该程序是SELECTcacheobjtype,objtype,usecounts,sqlFROMsys.syscacheobjectsWHEREsqlNOTLIKE'%cache%'ANDsqlNOTLIKE'%sys.%'ANDsqlNOTLIKE'%sp'executesrunsq_executesql的另一项强大功能与其相关接口,就是可以使用输出参数来返回调用批处理中的变量值。
此功能避免使用临时表返回数据,从而提高代码效率并减少重新编译。
设置和使用输出参数的语法与存储过程类似。
那是,声明参数时需要指定OUTPUT子句。
例如,以下静态代码演示了如何使用动态批处理中的输出参数@p将值返回到外部变量@i.DECLARE@sqlASNVARCHAR(12),@iASINT;SET@sql=N'批处理SET@p=10';EXECsp_executesql@sql,N'@pASINTOUTPUT',@p=@iOUTPUTSELECT@i--此代码返回10个输出。
使用字母N来标识Unicode字符串常量,总结以下几点:1.使用excesp_executesql比同类型的效率更高。
声明只需编译一次,而exec执行后需要多次编译。
2.动态sql的where子句,也就是说,在构造条件从句时,执行要进行定位,需要将变量转换为字符串并与动态sql.连接进行比较,这可能会导致Sql注入问题,如下所示:SET@sql='SELECT*FROM'+QUOTENAME(@TableName)+'WHEREOrderID='+CAST(@OrderIDASVARCHAR(50))+'ORDERBYORDERIDDESC'如果与execsp_executesql可以使用变量来确定位置并将值传递给该参数来构建动态sq。
我要避免Sql注入问题,如下所示:SET@sql='SELECT*FROM'+@TableName+'WHEREOrderID=@OIDORDERBYORDERIDDESC'3.Exec或Execsp_executesql。
如果你想让表格和列移动,名称表名约束和列名约束不能用于定位;要使用exec参数,需要表名参数和列名参数。
对于p_executesql;表名参数和列名参数不能指定为execsp_executesql的参数声明部分中指定的参数。
示例:代码createPROCEDUREGetData@tbNamenvarchar(10),@colNamenvarchar(10),@NamenvarqBEGINcharne(10@vare)50);set@sql='select'+@colName+'from'+@tbName+'wherename=@whereName';--这句话不能写成如下注:-set@sql='select@colNamefrom@tbNamewherename=@whereName';execsp_executesql@sql,N'@whereNamenvarchar(10)',@nameEND

mybatisifwhere标签怎么使用

MyBatis中中性文本的使用

在MyBatisXML文件中,``和``标签是动态SQL语句的重要元素。

1.当指定的条件为真时,“标签”的内容将包含在最终生成的SQL语句中。
其基本语法如下:

xml

SELECT*FROMyour_tableWHEREcondition_column=#{value}

上例中,当传入参数满足`condition`m当条件发生时,`tag'内的SQL语句将被执行。
这样可以根据不同的条件动态生成不同的SQL语句。

2.更有组织性。
其基本用法如下:

xml

SELECT*FROMyour_tableANDcondition_column1=#{value1}ANDcondition_column2=#{value2}

在此示例中``标签将了解ET连接器的过程,当两个“`标签中的条件都不满足时,生成的SQL语句中的WHERE子句不会被省略,而是会更改为正确的形式。
这种语法避免了遗漏的错误同时,``tag''还可以与其他MyBatis标签结合使用来生成更复杂的动态SQL。
通过使用这两个标签,可以大大提高SQL语句的灵活性和可用性。
在实际开发中,根据具体需求选择合适的语言使用方法,可以提高MGE效率和代码质量。

热门文章
1
SQL2000数据库备份压缩技巧:优化空... 怎么将SQL2000中的较大的备份数据库压缩变小更改数据库属性-选项-恢复模型很...

2
高效掌握:CMD命令轻松启动、关闭及登录... 如何用cmd命令快速启动和关闭mysql数据库服务开发中经常使用MySQL数据库...

3
SQL字符串处理技巧:单引号使用与转义标... SQL语句中,字符串类型的值均使用什么符号标明?单引号如果字符串内有单引号,请小...

4
Windows环境下Redis安装指南与... redis安装windowsredis基本简介与安装安装Redis首先需要获取安...

5
深度解析:Redis性能优势与局限性,助... redis有哪些优缺点?Redis的全称是RemoteDictionary.Se...

6
深入解析:MySQL数据库的特性与应用 mysql是什么MySQL是一个关系数据库管理系统。MySQL是一个开源关系数据...

7
MySQL命令行操作指南:轻松启动和登录... 用命令行方式启动和登录mysql服务的方法1.启动MySQL服务1打开命令行窗口...

8
Linux Redis后台启动教程:配置... linux怎么启动redis1、首先,为了管理方便,将Redis文件中的conf...

9
MySQL浮点数与Decimal类型详解... MySQL中的float和decimal类型有什么区别小数类型可以准确地表示非常...

10
C语言实现输入10个整数并找出最大最小值... C语言从键盘输入任意的10个整数,从中找出最大值和最小值并输出代码:#inclu...