SQLServer :exec与 exec "sp_executesql" 的用法

   sp_executesql 帮助文档: https://docs.microsoft.com/zh-cn/sql/relational-databases/system-stored-procedures/sp-executesql-transact-sql?view=sql-server-2017

           MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql。通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有。还有一个最大的好处就是利用sp_executesql,能够重用执行计划,这就大大提供了执行性能(对于这个我在后面的例子中会详加说明),还可以编写更安全的代码。EXEC在某些情况下会更灵活。除非您有令人信服的理由使用EXEC,否则尽量使用 sp_executesql.

EXEC命令有两种用法,一种是执行一个存储过程,另一种是执行一个动态的批处理。

sp_executesql命令在SQL Server中引入的比EXEC命令晚一些,它主要为重用执行计划提供更好的支持。

动态语句语法:
--方法1查询表改为动态
select * from sysobjects
exec('select ID,Name from sysobjects')
exec sp_executesql N'select ID,Name from sysobjects'--多了一个N为unicode
--方法2:字段名,表名,数据库名之类作为变量时,用动态SQL declare @FName varchar(20) set @FName='ID' exec('select '+@FName+' from sysobjects where '+@FName+'=5' ) declare @s varchar(1000) set @s=N'select '+@FName+' from sysobjects where '+@FName+'=5' exec sp_executesql @s--会报错 declare @s nvarchar(1000)--改为nvarchar set @s=N'select '+@FName+' from sysobjects where '+@FName+'=5' exec sp_executesql @s--成功

--方法3:输入参数 declare @i int,@s nvarchar(1000) set @i=5 exec('select ID,Name from sysobjects where ID='+@i) set @s='select ID,Name from sysobjects where ID=@i' exec sp_executesql @s,N'@i int',@i--此处输入参数要加上N

--方法4:输出参数 declare @i int,@s nvarchar(1000) set @s='select @i=count(1) from sysobjects' --用exec exec('declare @i int '+@s+' select @i')--把整个语句用字符串加起来执行 --用sp_executesql exec sp_executesql @s,N'@i int output',@i output--此处输出参数要加上N select @i

--方法5:输入输出 --用sp_executesql declare @i int,@con int,@s nvarchar(1000) set @i=5 select @s='select @con=count(1) from sysobjects where ID>@i' exec sp_executesql @s,N'@con int output,@i int',@con output ,@i select @con --用exec declare @i int,@s nvarchar(1000) set @i=5 select @s='declare @con int select @con=count(1) from sysobjects where ID> '+rtrim(@i)+' select @con' exec(@s)

 

补充:
1,它们之间最大的区别是嵌入式的参数,如下面一个语句 
declare @sql nvarchar(2000) 
declare @id varchar(20) 
set @id='1' 
set @sql='select count(*) from emp where id=' + @id 
exec @sql 
我想把得到的count(*)传出来,用传统的exec是不好办到的,但是用sp_executesql则很容易就办到了: 
declare @sql nvarchar(2000) 
declare @cou int 
declare @id varchar(20) 
set @id='1' 
set @sql='select @count=count(*) from emp where id=@id' 
exec sp_executesql @sql, N'@count int out,@id varchar(20)', @cou out 
,@id 
print @cou 
2.性能 
可以看到,如果用exec,由于每次传入的@id不一样,所以每次生成的@sql就不一样,这样每执行一次Sql2005就必须重新将要执行的动态Sql重新编译一次 
但是sp_executesql则不一样,由于将数值参数化,要执行的动态Sql永远不会变化,只是传入的参数的值在变化,那每次执行的时候就秒用重新编译,速度自然快多了哈! 

注意: 
1.sp_executesql要求动态Sql和动态Sql参数列表必须是Nvarchar,比如上个例子的@sql,N'@count int out,@id varchar(20)'我记得在sql2005中Varchar也可以的,但是我打了Sp3补丁后就不行了,必须为Nvarchar 
2.动态Sql的参数列表与外部提供值的参数列表顺序必需一致,如: 
N'@count int out,@id varchar(20)', @cou out,@id 
@count 对应 @cou,@id对应@id 
如果不一致,必须显式标明,如: 
N'@count int out,@id varchar(20)', @id=@id, @count=@cou out 
3.动态SQl的参数列表与外部提供参数的参数列表参数名可以同名

posted @ 2018-06-02 01:32  ParanoiaApe  阅读(905)  评论(0编辑  收藏  举报