SQL Server执行动态SQL正确方式

 我来答
华源网络
2022-11-10 · TA获得超过5599个赞
知道小有建树答主
回答量:2486
采纳率:100%
帮助的人:148万
展开全部

  SQL Server执行动态SQL的话 应该如何实现呢?下面就为您介绍SQL Server执行动态SQL两种正确方式 希望可以让您对SQL Server执行动态SQL有更深的了解

  动态SQL:code that is executed dynamically 它一般是根据用户输入或外部条件动态组合的SQL语句块 动态SQL能灵活的发挥SQL强大的功能 方便的解决一些其它方法难以解决的问题 相信使用过动态SQL的人都能体会到它带来的便利 然而动态SQL有时候在执行性能(效率)上面不如静态SQL 而且使用不恰当 往往会在安全方面存在隐患(SQL 注入式攻击)

  动态SQL可以通过EXECUTE 或SP_EXECUTESQL这两种方式来执行

  EXECUTE

  执行 Transact SQL 批中的命令字符串 字符串或执行下列模块之一:系统存储过程 用户定义存储过程 标量值用户定义函数或扩展存储过程 SQL Server 扩展了 EXECUTE 语句 以使其可用于向链接服务器发送传递命令 此外 还可以显式设置执行字符串或命令的上下文

  SP_EXECUTESQL

  执行可以多次重复使用或动态生成的 Transact SQL 语句或批处理 Transact SQL 语句或批处理可以包含嵌入参数 在批处理 名称作用域和数据库上下文方面 SP_EXECUTESQL 与 EXECUTE 的行为相同 SP_EXECUTESQL stmt 参数中的 Transact SQL 语句或批处理在执行 SP_EXECUTESQL 语句时才编译 随后 将编译 stmt 中的内容 并将其作为执行计划运行 该执行计划独立于名为 SP_EXECUTESQL 的批处理的执行计划 SP_EXECUTESQL 批处理不能引用调用 SP_EXECUTESQL 的批处理中声明的变量 SP_EXECUTESQL 批处理中的本地游标或变量对调用 SP_EXECUTESQL 的批处理是不可见的 对数据库上下文所作的更改只在 SP_EXECUTESQL 语句结束前有效

  如果只更改了语句中的参数值 则 sp_executesql 可用来代替存储过程多次执行 Transact SQL 语句 因为 Transact SQL 语句本身保持不变 仅参数值发生变化 所以 SQL Server 查询优化器可能重复使用首次执行时所生成的执行计划

  一般来说 我们推荐 优先使用SP_EXECUTESQL来执行动态SQL 一方面它更加灵活 可以有输入输出参数 另外一方面 查询优化器更有可能重复使用执行计划 提高执行效率 还有就是使用SP_EXECUTESQL能提高安全性;当然也不是说要完全摈弃EXECUTE 在特定场合下 EXECUTE比SP_EXECUTESQL更方便些 比如动态SQL字符串是VARCHAR类型 不是NVARCHAR类型 SP_EXECUTESQL 只能执行是Unicode的字符串或是可以隐式转换为ntext的常量或变量 而EXECUTE则两种类型的字符串都能执行

  下面我们来对比看看EXECUTE 和SP_EXECUTESQL的一些细节地方

  EXECUTE(N SELECT * FROM Groups ) 执行成功

  EXECUTE( SELECT * FROM Groups ) 执行成功

  SP_EXECUTESQL N SELECT * FROM Groups ; 执行成功

  SP_EXECUTESQL SELECT * FROM Groups 执行出错

  Summary:EXECUTE 可以执行非Unicode或Unicode类型的字符串常量 变量 而SP_EXECUTESQL只能执行Unicode或可以隐式转换为ntext的字符串常量 变量

  DECLARE @GroupName VARCHAR( );SET@GroupName = SuperAdmin ;

  EXECUTE( SELECT * FROM Groups WHERE GroupName= + SUBSTRING(@GroupName ) + ); SUBSTRING 附近有语法错误

  DECLARE @Sql VARCHAR( );

  DECLARE @GroupName VARCHAR( );SET@GroupName = SuperAdmin ;

  SET@Sql= SELECT * FROM Groups WHERE GroupName= + SUBSTRING(@GroupName ) +

   PRINT @Sql;EXECUTE(@Sql);

  Summary:EXECUTE 括号里面只能是字符串变量 字符串常量 或它们的连接组合 不能调用其它一些函数 存储过程等 如果要使用 则使用变量组合 如上所示

  DECLARE @Sql VARCHAR( );

  DECLARE @GroupName VARCHAR( );SET@GroupName = SuperAdmin ;

  SET@Sql= SELECT * FROM Groups WHEREGroupName=@GroupName

   PRINT @Sql;EXECUTE(@Sql); 出错:必须声明标量变量 “@GroupName” SET@Sql= SELECT * FROM Groups WHERE GroupName= + QUOTENAME(@GroupName )

  EXECUTE(@Sql); 正确:

  DECLARE @Sql NVARCHAR( );

  DECLARE @GroupName NVARCHAR( );SET@GroupName = SuperAdmin ;

  SET@Sql= SELECT * FROM Groups WHEREGroupName=@GroupName

  PRINT @Sql;

  EXEC SP_EXECUTESQL @Sql N @GroupNameNVARCHAR @GroupName

  查询出来没有结果 没有声明参数长度

  DECLARE @Sql NVARCHAR( );

  DECLARE @GroupName NVARCHAR( );SET@GroupName = SuperAdmin ;

  SET@Sql = SELECT * FROM Groups WHERE GroupName=@GroupName

  PRINT @Sql;

  EXEC SP_EXECUTESQL @Sql N @GroupName NVARCHAR( ) @GroupName

  Summary:动态批处理不能访问定义在批处理里的局部变量 SP_EXECUTESQL 可以有输入输出参数 比EXECUTE灵活

  下面我们来看看EXECUTE SP_EXECUTESQL的执行效率 首先把缓存清除执行计划 然后改变用@GroupName值SuperAdmin CommonUser CommonAdmin分别执行三次 然后看看其使用缓存的信息

  DBCC FREEPROCCACHE;

  DECLARE @Sql VARCHAR( );

  DECLARE @GroupName VARCHAR( );SET@GroupName = SuperAdmin ; CommonUser CommonAdmin

  SET@Sql = SELECT * FROM Groups WHERE GroupName= + QUOTENAME(@GroupName )

  EXECUTE(@Sql); SELECTcacheobjtype objtype usecounts sql

  FROM sys syscacheobjects

  WHERE sql NOTLIKE %cache%

  ANDsql NOTLIKE %sys % ;

  依葫芦画瓢 接着我们看看SP_EXECUTESQL的执行效率

  DBCC FREEPROCCACHE;

  DECLARE @Sql NVARCHAR( );

  DECLARE @GroupName NVARCHAR( );SET@GroupName = SuperAdmin ; CommonUser CommonAdmin

  SET@Sql = SELECT * FROM Groups WHERE GroupName=@GroupName

  EXECUTESP_EXECUTESQL @Sql N @GroupName NVARCHAR( ) @GroupName;

  SELECTcacheobjtype objtype usecounts sql

  FROM sys syscacheobjects

  WHERE sql NOTLIKE %cache%

  ANDsql NOTLIKE %sys % ;

lishixinzhi/Article/program/SQLServer/201311/22279

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式