动态sql语句基本语法--Exec与Exec sp_executesql 的区别
http://www.cnblogs.com/goody9807/archive/2010/10/19/1855697.html
动态sql语句基本语法
1 :普通SQL语句可以用Exec执行
eg: Select * from tableName
Exec( 'select * from tableName ')
Exec sp_executesql N 'select * from tableName ' -- 请注意字符串前一定要加N
2:字段名,表名,数据库名之类作为变量时,必须用动态SQL
eg:
declare @fname varchar(20) set @fname = 'FiledName '
Select @fname from tableName -- 错误,不会提示错误,但结果为固定值FiledName,并非所要。
Exec( 'select ' + @fname + ' from tableName ') -- 请注意 加号前后的 单引号的边上加空格
当然将字符串改成变量的形式也可
declare @fname varchar(20) set @fname = 'FiledName ' --设置字段名
declare @s varchar(1000) set @s = 'select ' + @fname + ' from tableName ' Exec(@s) -- 成功
exec sp_executesql @s -- 此句会报错
declare @s Nvarchar(1000) -- 注意此处改为nvarchar(1000)
set @s = 'select ' + @fname + ' from tableName '
Exec(@s) -- 成功
exec sp_executesql @s -- 此句正确
3. 输出参数
declare @num int, @sql nvarchar(4000)
set @sql= 'select count(*) from tableName '
exec(@sql)
--如何将exec执行结果放入变量中?
declare @num int, @sql nvarchar(4000)
set @sql= 'select @a=count(*) from tableName '
exec sp_executesql @sql,N '@a int output ',@num output select @num
-----------------------
@maxnum int output --最大数量
declare @idcount int --用于存储 exec 语句赋值的变量
declare @maxpagesql nvarchar(300) --一定要nvarchaar
set @maxpagesql = 'select @idcount=count(id) from QuestionInfo where 1=1 '
exec sp_executesql @maxpagesql,N'@idcount int output ',@maxnum output
select @maxnum
动态SQL EXEC(http://www.cnblogs.com/Junelee1211/archive/2011/08/25/2153024.html)
1、EXEC命令的括号中只允许包含一个字符串变量,或者一个 字符串文本,或者字符串变量与字符串文本的串联。不能再括号中使用函数或CASE表达式,如下面尝试在括号中调用QUOTENAME函数以引用对象名称,运行将失败:
1: DECLARE @schemaname NVARCHAR(255),@tablename NVARCHAR(128)
2: SET @schemaname='dbo'
3: SET @tablename='Order Details'
4:
5: EXEC (N'SELECT COUNT(*) FROM '+QUOTENAME(@schemaname)+N'.'+QUOTENAME(@tablename)+N';')
上述代码将会产生如下错误:
消息 102,级别 15,状态 1,第 5 行 'QUOTENAME' 附近有语法错误。 SQL Server 分析和编译时间: CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 执行时间: CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
所以做好的方法是把代码构造到一个变量中,这样就不会受限制了,然后再把该变量作为EXEC命令的输入参数,就像这样:
1: DECLARE @schemaname NVARCHAR(255) ,
2: @tablename NVARCHAR(128) ,
3: @sql NVARCHAR(MAX)
4: SET @schemaname = 'dbo'
5: SET @tablename = 'Order Details'
6: SET @sql = N'SELECT COUNT(*) FROM ' + QUOTENAME(@schemaname) + N'.'
7: + QUOTENAME(@tablename) + N';'
8: EXEC (@sql)
2、EXEC不提供接口。EXEC(<string>)不提供接口。它唯一的输入就是包含你要调用代码的字符串。动态批处理不能访问在调用批处理中定义的局部变量。如下面代码尝试访问定义在调用批处理中的变量将失败。
1: DECLARE @i INT
2: SET @i = 10248
3:
4: DECLARE @sql NVARCHAR(MAX)
5:
6: SET @sql = 'SELECT * FROM dbo.Orders WHERE OrderID=@i;'
7: EXEC(@sql)
将产生如下错误:
消息 137,级别 15,状态 2,第 1 行 必须声明标量变量 "@i"。
使用EXEC时,如果想访问变量,必须把变量内容串联到动态构建的 代码字符串中。
DECLARE @i INT
SET @i = 10248 DECLARE @sql NVARCHAR(MAX) SET @sql = 'SELECT * FROM dbo.Orders WHERE OrderID='
+ CAST(@i AS NVARCHAR(10)) + ';'
EXEC(@sql)
这样就没有问题了。
如果一个变量包含字符串,把该变量的内容串联到代码将会导致安全风险(SQL注入),为了避免SQL注入,可以吧字符串大小限制为所需的最小长度。当然,实际中这种情况根本不需要动态SQL直接执行SQL语句就可以,这个示例只是为了演示。
串联变量的内容存在性能方面的弊端,SQL Server将为每个唯一的查询字符串创建新的即席执行计划,即使查询模式相同也是这样的。为演示这一点,先清空缓存中的执行计划。
DBCC FREEPROCCACHE
1: SELECT cacheobjtype ,
2: objtype ,
3: usecounts ,
4: sql
5: FROM sys.syscacheobjects
6: WHERE sql NOT LIKE '%cache%'
7: AND sql NOT LIKE '%sys.%'
得到查询结果:
cacheobjtype objtype usecounts sql Compiled Plan Adhoc 1 SELECT * FROM dbo.Orders WHERE OrderID=10250; Compiled Plan Adhoc 1 SELECT * FROM dbo.Orders WHERE OrderID=10248; Compiled Plan Prepared 3 (@1 smallint)SELECT * FROM [dbo].[Orders] WHERE [OrderID]=@1 Compiled Plan Adhoc 4 SET STATISTICS IO ON SET STATISTICS TIME ON Compiled Plan Adhoc 1 SELECT * FROM dbo.Orders WHERE OrderID=10249; Compiled Plan Adhoc 4 SET STATISTICS IO OFF SET STATISTICS TIME OFF
EXEC除了不支持动态批处理中的输入参数外,也不支持输出参数。默认情况下,EXEC把查询输出返回给调用者。如果你想把输出结果返回给调用批处理中的变量,事情就没那么简单了,为此,你需要使用INSERT EXEC把输出插入到一个目的表,然后再从该表中取值,赋给该变量,就像这样:
1: DECLARE @schemaname NVARCHAR(128) ,
2: @tablename NVARCHAR(128) ,
3: @colname NVARCHAR(128) ,
4: @sql NVARCHAR(MAX) ,
5: @cnt INT
6:
7: SET @schemaname = 'dbo'
8: SET @tablename = 'Orders'
9: SET @colname = 'CustomerID'
10:
11: SET @sql = N'SELECT COUNT(DISTINCT ' + QUOTENAME(@colname) + ') FROM '
12: + QUOTENAME(@schemaname) + N'.' + QUOTENAME(@tablename) + N';'
13:
14: CREATE TABLE #T1 ( cnt INT )
15: INSERT INTO #T1
16: EXEC ( @sql
17: )
18: SELECT @cnt = cnt
19: FROM #T1
20: SELECT @cnt
21: DROP TABLE #T1
3、在SQL Server2000中串联变量值时,EXEC比sp_executesql多一个优势,它支持更长的代码,尽管技术上sp_executesql的输入代码字符串是NTEXT类型的,但你一般是在局部变量中构造代码字符串。而你又不能用大型对象类型声明局部变量,所以,实际上在sp_executesql中执行的查询字符串被限制为Unicode字符串(NVARCHAR)支持的最大长度4000,而EXEC支持常规字符串(VARCHAR)允许最大8000个字符。另外EXEC还支持一个特殊的功能,它允许你在括号中串联多个变量,每个变量都支持8000个字符的长度。
在SQL Server2005中,就不用这么纠结了,因为可以为EXEC命令提供一个VARCHAR(MAX)或NVARCHAR(MAX)的变量作为输入,输入字符串可以达到2GB大小
动态sql语句基本语法--Exec与Exec sp_executesql 的区别的更多相关文章
- [SQL]动态sql语句基本语法
动态sql语句基本语法 :普通SQL语句可以用Exec执行 eg: Select * from tableName Exec('select * from tableName') Exec sp_ex ...
- 动态sql语句基本语法
1 普通sql语句可以用exec执行,如: SELECT * FROM video EXEC ('SELECT * FROM video') EXEC sp_executesql N'SELECT * ...
- MySQL基础----动态SQL语句
尊重原创:http://blog.csdn.net/abc19900828/article/details/39501643 动态sql语句基本语法 1 :普通SQL语句可以用Exec执行 eg: ...
- 用sp_executesql执行动态SQL语句及获得返回值
过去我执行拼凑出来的动态SQL语句,都直接使用EXEC @sql 的方式.有好几次,都看到有资料说,应该尽量使用 sp_executesql. 究其原因,是因为仅仅参数不同的情况下,sp_execut ...
- MyBatis学习总结_11_MyBatis动态Sql语句
MyBatis中对数据库的操作,有时要带一些条件,因此动态SQL语句非常有必要,下面就主要来讲讲几个常用的动态SQL语句的语法 MyBatis中用于实现动态SQL的元素主要有: if choose(w ...
- MyBatis学习总结(11)——MyBatis动态Sql语句
MyBatis中对数据库的操作,有时要带一些条件,因此动态SQL语句非常有必要,下面就主要来讲讲几个常用的动态SQL语句的语法 MyBatis中用于实现动态SQL的元素主要有: if choose(w ...
- 动态SQL的执行,注:exec sp_executesql 其实可以实现参数查询和输出参数的
本文转自:http://www.cnblogs.com/hnsdwhl/archive/2011/07/23/2114730.html 当需要根据外部输入的参数来决定要执行的SQL语句时,常常需要动态 ...
- 存储过程中执行动态Sql语句
MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...
- 怎样SQL存储过程中执行动态SQL语句
MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...
随机推荐
- css中文乱码与替换字符
有时候,我们的css样式表中字体乱码,很诧异.百度谷歌是两个老师,有时jquery博客还上淘宝,那边有现成的代码,看看,发现里面定义全局字体是这样的font:12px/1.5 tahoma,arial ...
- macbook air 128g 磁盘清理
使用 du 命令发现 ~/Library/Developer/Xcode/DerivedData 占用了大量空间,这些都是xcode对以前建过的project源码文件建立的索引等,如果不需要可以都删 ...
- BZOJ 3270 && BZOJ 1778 (期望DP && 高斯消元)
BZOJ 3270 :设置状态为Id(x,y)表示一人在x,一人在y这个状态的概率. 所以总共有n^2种状态. p[i]表示留在该点的概率,Out[i]=(1-p[i])/Degree[i]表示离开该 ...
- Pip install lxml centOSFailed building wheel for lxml
转到虚拟环境目录:yum install libxslt-devel libxml2-devel yum install python-devel pip install lxml
- flash2x、flax
http://flax.so/ 牛客网 LeetCode Online Judge
- easyui 筛选数据及仅允许选择数据
先说需求,本地已缓存数据源,用户输入拼音码或编号,筛选数据作为新的数据源,然后通过键盘选择. 再说问题,easyui combogrid控件,在mode为local,也就是将数据源缓存在本地的情况下, ...
- Ansible-Tower快速入门-3.快速开始【翻译】
快速开始 当你完成安装tower后,我们应该完成接下来的一些任务,并通过使用tower,快速设置和启动我们的第一个ansible playbooks.这第一个playbooks的启动会执行简单的ans ...
- RabbitMQ在window的搭建
RabbitMq window 搭建设置过程,网上有些说的不太明白,所以亲自操刀测试过程,参考了很多人的资料,多谢各位大神的宝贵资料第一步:装RabbitMq运行环境,类似一个虚拟机的东东 1.otp ...
- LPTHW 笨办法学python 37章 python关键字/关键词介绍
本章简要的介绍了各种关键词: and:[布尔运算]且 del: 删除变量(函数,类) from: 从某一个库或者文件读取 not:[布尔运算]非 while: while-loop 关键字,后跟循环条 ...
- K - Least Common Multiple
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Descr ...