一、exec和sp_executesql介绍

当需要根据外部输入的参数来决定要执行的SQL语句时,常常需要动态来构造SQL查询语句。比如,一个比较通用的分页存储过程,可能需要传入表名,字段,过滤条件,排序等参数,而对于搜索的话,可能要根据搜索条件判断来动态执行SQL语句。

  在SQL Server中有两种方式来执行动态SQL语句,分别是execsp_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. ACM学习历程—HDU2476 String painter(动态规划)

    http://acm.hdu.edu.cn/showproblem.php?pid=2476 题目大意是给定一个起始串和一个目标串,然后每次可以将某一段区间染成一种字符,问从起始串到目标串最少需要染多 ...

  2. coredns 代理consul 运行noamd 部署的应用

    nomad 是一个方便的应用调度平台,consul 一个很不错的服务发现工具,coredns 很不错, 扩展性比较强的dns 服务器,集成起来可能做很强大的事情 我的运行环境是mac,实际情况按需部署 ...

  3. jQuery因mouseover,mouseout冒泡产生的闪烁问题

    由于浏览器的冒泡行为.造成如果在一个DIV元素上同时定义了mouseover,mouseout的时候,当鼠标移动到DIV中的child子元素的时候,就会同时执行了两个操作mouseover和mouse ...

  4. vs2013突然没有代码提示功能了。

    工具->选项->文本编辑器->C++ ->高级->禁用IntelliSense设置 false 然后选确定.

  5. Spring Could 问题

    作为流行的微服务框架,Spring Could实用但不完美,比如说它只针对Java语言,坚持REST协议做微服务间的通讯等. Spring Cloud虽然集成了众多组件,可以构建一个完整的微服务应用, ...

  6. emacs之配置代码风格

    emacsConfig/code-style-setting.el (add-hook 'c-mode-common-hook ( lambda() ( c-set-style "java& ...

  7. postman全方位讲解(有空看下)

    Postman 接口测试神器 Postman 是一个接口测试和 http 请求的神器,非常好用. 官方 github 地址: https://github.com/postmanlabs Postma ...

  8. [java]经验集

    Calendar c = Calendar.getInstance(); c.set(1999,12,21); SimpleDateFormat sdf = new SimpleDateFormat( ...

  9. 简易的RPC调用框架(大神写的)

    RPC,即 Remote Procedure Call(远程过程调用),说得通俗一点就是:调用远程计算机上的服务,就像调用本地服务一样. RPC 可基于 HTTP 或 TCP 协议,Web Servi ...

  10. servlet中获取配置文件中的参数.

    web.xml (添加init-param) <?xml version="1.0" encoding="UTF-8"?> <web-app ...