动态执行SQL语句,接收返回值
一、exec和sp_executesql介绍
当需要根据外部输入的参数来决定要执行的SQL语句时,常常需要动态来构造SQL查询语句。比如,一个比较通用的分页存储过程,可能需要传入表名,字段,过滤条件,排序等参数,而对于搜索的话,可能要根据搜索条件判断来动态执行SQL语句。
在SQL Server中有两种方式来执行动态SQL语句,分别是exec和sp_executesql。sp_executesql相对而言具有更多的优点,它提供了输入输出接口,可以将输入输出变量直接传递到SQL语句中,而exec只能通过拼接的方式来实现。还有一个优点就是sp_executesql,能够重用执行计划,这就大大提高了执行的性能。所以一般情况下建议选择sp_executesql来执行动态SQL语句。
使用sp_executesql需要注意的一点就是,它后面执行的SQL语句必须是Unicode编码的字符串,所以在声明存储动态SQL语句的变量时必须声明为nvarchar类型,否则在执行的时候会报“过程需要类型为 'ntext/nchar/nvarchar' 的参数 '@statement'”的错误,如果是使用sp_executesql直接执行SQL语句,则必须在前面加上大写字母N,以表明后面的字符串是使用Unicode类型编码的。
在SQL中,字符串前加N,表示双字节字符,即字符串用Unicode方式存储。对于西文字符,用一个字节来存储过足够了,对于东方文字字符,就需要两个字节来存储。Unicode 为了统一、规范、方便、兼容,就规定西文字符也用两个字节来存储。
下面看几种不同的动态执行SQL的例子
--1,普通SQL
exec ('select GETDATE();');
exec sp_executesql N'select GETDATE();';--加上N,不用Unicode表示方式会报错
--2,带参数的SQL语句
declare @tempsql nvarchar(1024);
declare @start_date datetime;
set @start_date = '2018-12-24';
set @tempsql = 'select DATEDIFF(day, @start_date,GETDATE());';
exec('select DATEDIFF(day, ''' + @start_date + ''',GETDATE());')
exec sp_executesql @tempsql, N'@start_date datetime',@start_date;
--3,有返回值的SQL语句
declare @tempsql nvarchar(1024);
declare @temp datetime;
set @tempsql = N'select @temp = GETDATE();';
exec sp_executesql @tempsql,N'@temp datetime output',@temp output;
select @temp
执行普通SQL时,exec和sp_executesql没有太大差别。
执行带参数的sql时,exec只能以字符串拼接的方式执行,sp_executesql可以以传参的方式执行,更安全一些
执行有返回值的sql时,只能使用sp_executesql
二、存储过程中动态执行SQL,并且获取执行的值
假如在存储过程中需要动态执行SQL,并且还要把动态执行的结果,比如行数、sum的总数等,赋值给变量,或者赋值到临时表里,那么就可以用exec和sp_executesql结合使用,如下例子
IF object_id('tempdb..#tempTB') IS NOT NULL
BEGIN
DROP TABLE #tempTB
END
--创建临时表
CREATE TABLE #tempTB(
testTime datetime NULL,
testTime2 datetime NULL,
)
--将查询的数据insert到临时表
declare @tempSQL nvarchar(1000);
set @tempSQL = 'insert into #tempTB (testTime,testTime2) select GETDATE(), DATEADD(day, 1,GETDATE());';
exec(@tempSQL);
select * from #tempTB;
--动态查询临时表行数,并赋值到变量
declare @tempCon int;
set @tempSQL = N'select @tempCon = count(*) from #tempTB;';
exec sp_executesql @tempSQL,N'@tempCon int output',@tempCon output;
select @tempCon;
DROP TABLE #tempTB
动态执行SQL语句,接收返回值的更多相关文章
- sp_executesql得到执行sql语句的返回值
执行 sql语句,得到 变量的值 ' declare @Partition int; ); ); SET @SQLString = N'SELECT @RangeKeyOUT = $PARTITION ...
- 第二百八十七节,MySQL数据库-条件语句、循环语句、动态执行SQL语句
MySQL数据库-条件语句.循环语句.动态执行SQL语句 1.if条件语句 delimiter \\ CREATE PROCEDURE proc_if () BEGIN ; THEN ; ELSEIF ...
- 使用exec和sp_executesql动态执行SQL语句(转载)
当需要根据外部输入的参数来决定要执行的SQL语句时,常常需要动态来构造SQL查询语句,个人觉得用得比较多的地方就是分页存储过程和执行搜索查询的SQL语句.一个比较通用的分页存储过程,可能需要传入表名, ...
- ORACLE 查询不走索引的原因分析,解决办法通过强制索引或动态执行SQL语句提高查询速度
(一)索引失效的原因分析: <>或者单独的>,<,(有时会用到,有时不会) 有时间范围查询:oracle 时间条件值范围越大就不走索引 like "%_" ...
- sp_executesql动态执行sql语句并将结果赋值给一变量
需求场景: 需动态拼接sql语句进行执行,并将执行的结果赋值给一指定变量. 样例代码如下: SELECT @tableName = TAB_NAME FROM dbo.NMR_BLYWBDY WHER ...
- 接收sql语句的返回值
首先,简要介绍一下我们需要什么? 我们想在sql中用 try...catch,如果成功,就返回我们查询的值,如果失败就返回-1 所以有了以下sql语句(写在后台的) string myInsert = ...
- [转]ORACLE 动态执行SQL语句
本文转自:http://zhaisx.iteye.com/blog/856472 Oracle 动态SQLOracle 动态SQL有两种写法:用 DBMS_SQL 或 execute immediat ...
- 动态执行SQL语句
在实际制作过程中,需要动态的拼接SQL语句然后执行.具体代码如下: declare @columnName varchar(20),@tempName varchar(20) select @temp ...
- 自定义函数动态执行SQL语句
Oracle 动态SQL有两种写法:用 DBMS_SQL 或 execute immediate,建议使用后者. DDL 和 DML Sql代码 收藏代码 /*** DDL ***/ begin EX ...
随机推荐
- java面试题6
1.写一个冒泡排序的算法 升序排列: int[] nums = {5,6,9,10,20,30,28,27,15}; for(int i = 0;i<nums.length;i++){ for( ...
- WindowsXamlHost:在 WPF 中使用 UWP 控件库中的控件
在 WindowsXamlHost:在 WPF 中使用 UWP 的控件(Windows Community Toolkit) 一文中,我们说到了在 WPF 中引入简单的 UWP 控件以及相关的注意事项 ...
- iis6 , URL重写HTM文件名后,出现真实的HTM文件不能访问的解决
服务器环境是windows 2003 IIS6 在web.config文件中加入 1.在<compilation debug="true"> 节点加入 <buil ...
- 6-11 Level-order Traversal(25 分)
Write a routine to list out the nodes of a binary tree in "level-order". List the root, th ...
- test20181019 B君的第二题
题意 分析 快速子集和变换以及快速超集和变换的裸题. 用\(f(s)\)表示集合s的方案数,初始化为输入中s出现的次数. 做一遍快速子集和变换,此时f(s)表示s及其子集在输入中出现的次数. 对所有f ...
- nodejs json-t 基本测试
安装npm包 npm i json-templater or yarn add json-templater 基本代码 var render = require('json-templater/str ...
- ballerina 学习二十四 监控ballerina
ballerina 服务的监控还是比较方便的,以及集成了Prometheus Grafana Jaeger Elastic Stack 监控服务监控的集成 主要包含以下几个步骤 a. 安装docker ...
- 根据tomcat的日志判断web的发布路径以及服务路径
[ContainerBackgroundProcessor[StandardEngine[Catalina]]] org.apache.catalina.startup.HostConfig.unde ...
- TongWEB与JOnAS 对比,国产中间件战斗机东方通TongWEB源码解析
转自网址: http://bbs.51cto.com/thread-489819-1-1.html 首先需要声明的是,本人出于技术爱好的角度,以下的文字只是对所看到的一些情况的罗列,偶尔附加个人的一些 ...
- ASI和TS流有什么区别
TS流是信源码流,最高码率为44.209 Mbit/s,它是经过信源编码后的压缩码流,为了使欲传输的信源信息在传输速率一定的条件下更快更多地传输,还要把数据进行压缩,也就是通过信源编码去掉信息中多余的 ...