4. 执行动态SQL语句
这里首先解释一下什么叫做动态SQL语句,这里说的动态SQL语句指的就是在SQL脚本比如存储过程中动态组装的SQL语句。比如一条查询语句,根据条件的不同,我们选择的表名、列或者where条件都可能不同。
SQL Server中有两个可以执行动态SQL语句的存储过程,sp_sqlExec和sp_executesql。sp_executesql 与sp_sqlExec一个明显区别是,sp_executesq可用通过参数方式来执行SQL,并且能够返回动态SQL语句的输出参数。
sp_sqlExec
这个存储过程在作用其实是和使用Execute/Exec表达式执行动态SQL的作用是一样的。也就是说Sp_sqlExec(@statement) 和 Exec(@statement) 的作用一样,这个通过查看Sp_sqlExec的创建脚本能够得到验证。
需要注意的是,Sp_sqlExec和Exec所执行的sql脚本的上下文和调用Sp_sqlExec的上下文是不同的,也就是说在当前调用的Sp_sqlExec的程序中声明的变量并不能从Sp_sqlExec执行的SQL语句中访问。
• 示例
如下的代码演示了一个动态SQL语句被组装的过程。这个存储过程的功能是返回tbl_Test中的数据,并且根据提供的字段进行排序。
sp_executesqlcreate procedure sp_GetTestData
(@orderByField as varchar(20)=null)
as
begin
declare @statement varchar(1024)
set @statement = 'select * from tbl_Test'
if @orderByField<>null
begin
set @statement = @statement+' order by ' + @orderByField
end
exec sp_sqlexec @statement
end
这个以“sp”开头的存储过程实际上是一个“xp”(extended stored procedure),有点挂羊头卖狗肉的味道。Microsoft还有很多其他这样的以”sp”开头的“xp”,想必自有他们的道理,不过我暂时还没有弄清楚。
sp_executesq通过参数替换的方式,也可以用来执行一些查询结构固定而仅仅是参数不同的SQL语句,相对于sp_sqlExec/Execute执行一个组装好的sql字符串来说,通过参数替换方式执行sp_executesql还有如下优势:
1) 多次执行的性能得到优化。如果多次调用SQL语句,我们只需要改变输入参数的取值,而传入的T-SQL脚本是和上一次完全一样的,查询优化器就能够那第二次执行的T-SQL脚本和第一次执行的SQL脚本进行匹配,并且执行上一次产生的执行计划,这样SQL Server就不需要再对这条语句进行重新编译,从而获得更高的效率。
2) T-SQL 语句只需要一次就能够组装好,也就是不需要将一些固定的SQL表达式和一些变量进行组装。
3) 非字符串类型的变量比如整形变量能够保持本来的形式。另外普通字符串也不需要进行象Unicode字符串的转化了。
• 定义

• 示例
下面的脚本演示了如何通过参数的方式来调用存储过程,并且获取输出参数的结果。
DECLARE @IntVariable int;
DECLARE @SQLString nvarchar(500);
DECLARE @ParmDefinition nvarchar(500);
DECLARE @max_title varchar(30);
SET @IntVariable = 197;
SET @SQLString = N'SELECT @max_titleOUT = max(Title)
FROM AdventureWorks.HumanResources.Employee
WHERE ManagerID = @level';
SET @ParmDefinition = N'@level tinyint, @max_titleOUT varchar(30) OUTPUT';
EXECUTE sp_executesql @SQLString, @ParmDefinition, @level = @IntVariable, @max_titleOUT=@max_title OUTPUT;
SELECT @max_title;