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
将上端代码执行三次,分别为@i赋值10248,10249和10250,然后使用下面的代码查询

   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 的区别的更多相关文章

  1. [SQL]动态sql语句基本语法

    动态sql语句基本语法 :普通SQL语句可以用Exec执行 eg: Select * from tableName Exec('select * from tableName') Exec sp_ex ...

  2. 动态sql语句基本语法

    1 普通sql语句可以用exec执行,如: SELECT * FROM video EXEC ('SELECT * FROM video') EXEC sp_executesql N'SELECT * ...

  3. MySQL基础----动态SQL语句

    尊重原创:http://blog.csdn.net/abc19900828/article/details/39501643   动态sql语句基本语法 1 :普通SQL语句可以用Exec执行 eg: ...

  4. 用sp_executesql执行动态SQL语句及获得返回值

    过去我执行拼凑出来的动态SQL语句,都直接使用EXEC @sql 的方式.有好几次,都看到有资料说,应该尽量使用 sp_executesql. 究其原因,是因为仅仅参数不同的情况下,sp_execut ...

  5. MyBatis学习总结_11_MyBatis动态Sql语句

    MyBatis中对数据库的操作,有时要带一些条件,因此动态SQL语句非常有必要,下面就主要来讲讲几个常用的动态SQL语句的语法 MyBatis中用于实现动态SQL的元素主要有: if choose(w ...

  6. MyBatis学习总结(11)——MyBatis动态Sql语句

    MyBatis中对数据库的操作,有时要带一些条件,因此动态SQL语句非常有必要,下面就主要来讲讲几个常用的动态SQL语句的语法 MyBatis中用于实现动态SQL的元素主要有: if choose(w ...

  7. 动态SQL的执行,注:exec sp_executesql 其实可以实现参数查询和输出参数的

    本文转自:http://www.cnblogs.com/hnsdwhl/archive/2011/07/23/2114730.html 当需要根据外部输入的参数来决定要执行的SQL语句时,常常需要动态 ...

  8. 存储过程中执行动态Sql语句

    MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...

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

    MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...

随机推荐

  1. 第7章 LED将为我闪烁:控制发光二极管

    所谓I/O内存是通过各种接口连接到主机的硬件在主机内存的映射.LED驱动还提供了两种交互方式:命令和读写设备文件. 创建设备文件的步骤: 第1步:使用cdev_init函数初始化cdev 第2步:指定 ...

  2. 自动化工具selenium

    selenium web 自动化工具 selenium 不仅仅可以做web自动化,还可以考虑用于爬虫 java.python..net都可使用,具体使用方法google 构建Python+Seleni ...

  3. liunx中字符驱动编写的简单模板

    下面是关于字符驱动两个程序,主要是说明驱动编写的思想,理解驱动是怎么一步一步被实现的. 驱动的第一个实现程序,是相对于裸机编程的,主要是体会一下驱动编程思想: cdev.h: 所包含的头文件 #ifn ...

  4. SqlServer性能优化 性能调控(十)

    如何做资源的调控: 1.建立资源池. 2.创建工作负荷组 create resource pool ImporPool with ( min_cpu_percent=30,max_cpu_percen ...

  5. CSS元素定位6-10课

    <精通CSS.DIV网页样式与布局>视频6-10课总结图: 元素定位 (1)float:left/right; 左浮动:脱离普通文档流向左浮动(即向左对齐):float属性必须应用在块级元 ...

  6. 前端开发薪资之各地区对比(图文分析)(share)

    发现最近大家都在关注有关前端开发的薪资问题,不同地方各有差异,今天我就总结一下发出来方便大家的查阅.(2014年) 前面给大家介绍了关于前端开发需要学习的东西,根据你掌握的技能程度,薪水是不一样的.d ...

  7. jenkins 使用oclint 扫描 oc 代码

    jenkins 环境的搭建,在这里不在赘述,下面我们写一写,如何接入oclint. OCLint是一个强大的静态代码分析工具,可以用来提高代码质量,查找潜在的bug,主要针对c,c++和Objecti ...

  8. ie8的兼容

    1.IE8以下不支持getElementsByClassName方法//解决IE8之类不支持getElementsByClassNameif (!document.getElementsByClass ...

  9. python 获取html源代码里标签之间的文本用get_text()

    例: 输出<span class="w-txt">分享</span>中的文本"分享" contents = bsObj.find_all ...

  10. 如何配置Windows 防火墙,允许SQL Server的远程连接

    一.如何找到SQL Server正在侦听的TCP端口,可以按一下步骤: 1.打开 SQL Server 配置管理器中,从开始->所有程序-> Microsoft SQL Server 20 ...