一、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语句,接收返回值的更多相关文章

  1. sp_executesql得到执行sql语句的返回值

    执行 sql语句,得到 变量的值 ' declare @Partition int; ); ); SET @SQLString = N'SELECT @RangeKeyOUT = $PARTITION ...

  2. 第二百八十七节,MySQL数据库-条件语句、循环语句、动态执行SQL语句

    MySQL数据库-条件语句.循环语句.动态执行SQL语句 1.if条件语句 delimiter \\ CREATE PROCEDURE proc_if () BEGIN ; THEN ; ELSEIF ...

  3. 使用exec和sp_executesql动态执行SQL语句(转载)

    当需要根据外部输入的参数来决定要执行的SQL语句时,常常需要动态来构造SQL查询语句,个人觉得用得比较多的地方就是分页存储过程和执行搜索查询的SQL语句.一个比较通用的分页存储过程,可能需要传入表名, ...

  4. ORACLE 查询不走索引的原因分析,解决办法通过强制索引或动态执行SQL语句提高查询速度

    (一)索引失效的原因分析: <>或者单独的>,<,(有时会用到,有时不会) 有时间范围查询:oracle 时间条件值范围越大就不走索引 like "%_" ...

  5. sp_executesql动态执行sql语句并将结果赋值给一变量

    需求场景: 需动态拼接sql语句进行执行,并将执行的结果赋值给一指定变量. 样例代码如下: SELECT @tableName = TAB_NAME FROM dbo.NMR_BLYWBDY WHER ...

  6. 接收sql语句的返回值

    首先,简要介绍一下我们需要什么? 我们想在sql中用 try...catch,如果成功,就返回我们查询的值,如果失败就返回-1 所以有了以下sql语句(写在后台的) string myInsert = ...

  7. [转]ORACLE 动态执行SQL语句

    本文转自:http://zhaisx.iteye.com/blog/856472 Oracle 动态SQLOracle 动态SQL有两种写法:用 DBMS_SQL 或 execute immediat ...

  8. 动态执行SQL语句

    在实际制作过程中,需要动态的拼接SQL语句然后执行.具体代码如下: declare @columnName varchar(20),@tempName varchar(20) select @temp ...

  9. 自定义函数动态执行SQL语句

    Oracle 动态SQL有两种写法:用 DBMS_SQL 或 execute immediate,建议使用后者. DDL 和 DML Sql代码 收藏代码 /*** DDL ***/ begin EX ...

随机推荐

  1. java面试题6

    1.写一个冒泡排序的算法 升序排列: int[] nums = {5,6,9,10,20,30,28,27,15}; for(int i = 0;i<nums.length;i++){ for( ...

  2. WindowsXamlHost:在 WPF 中使用 UWP 控件库中的控件

    在 WindowsXamlHost:在 WPF 中使用 UWP 的控件(Windows Community Toolkit) 一文中,我们说到了在 WPF 中引入简单的 UWP 控件以及相关的注意事项 ...

  3. iis6 , URL重写HTM文件名后,出现真实的HTM文件不能访问的解决

    服务器环境是windows 2003 IIS6 在web.config文件中加入 1.在<compilation debug="true"> 节点加入 <buil ...

  4. 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 ...

  5. test20181019 B君的第二题

    题意 分析 快速子集和变换以及快速超集和变换的裸题. 用\(f(s)\)表示集合s的方案数,初始化为输入中s出现的次数. 做一遍快速子集和变换,此时f(s)表示s及其子集在输入中出现的次数. 对所有f ...

  6. nodejs json-t 基本测试

    安装npm包 npm i json-templater or yarn add json-templater 基本代码 var render = require('json-templater/str ...

  7. ballerina 学习二十四 监控ballerina

    ballerina 服务的监控还是比较方便的,以及集成了Prometheus Grafana Jaeger Elastic Stack 监控服务监控的集成 主要包含以下几个步骤 a. 安装docker ...

  8. 根据tomcat的日志判断web的发布路径以及服务路径

    [ContainerBackgroundProcessor[StandardEngine[Catalina]]] org.apache.catalina.startup.HostConfig.unde ...

  9. TongWEB与JOnAS 对比,国产中间件战斗机东方通TongWEB源码解析

    转自网址: http://bbs.51cto.com/thread-489819-1-1.html 首先需要声明的是,本人出于技术爱好的角度,以下的文字只是对所看到的一些情况的罗列,偶尔附加个人的一些 ...

  10. ASI和TS流有什么区别

    TS流是信源码流,最高码率为44.209 Mbit/s,它是经过信源编码后的压缩码流,为了使欲传输的信源信息在传输速率一定的条件下更快更多地传输,还要把数据进行压缩,也就是通过信源编码去掉信息中多余的 ...