sp_executesql
这是一个系统存储过程中的数据库引擎存储过程, 其功能是:
执行一个可以被重复使用多次的Transact-SQL语句或语句群组, 或者是动态创建的SQL语句. 这里的语句或语句群组可以包含内嵌的参数.
语法:
sp_executesql [ @statement = ] statement
[
{ , [ @params = ] N'@parameter_name data_type [ OUT | OUTPUT ][ ,...n ]' }
{ , [ @param1 = ] 'value1' [ ,...n ] }
]
参数:
[ @statement = ] statement
这应该是一个包含Transact-SQL语句的Unicode的字符串. 复杂的Unicode字符串这里是不支持的, 比如说使用'+'拼接的字符串就不支持. 字符串常量不支持. 如果是指定Unicode常量, 那么它的前面必须用一个大写的N来做前缀. 比如, Unicode常量N'sp_who' 是合法的. 而字符串常量就不合法. 字符串的尺寸取决于服务器上可用的内存数量. 在64位机器上, 这个字符串的上限是2GB, 即nvarchar(max)的上限.
返回值:
0代表成功
非0代表失败
返回结果集:
取决于其中的SQL语句.
要点:
1. 与EXECUTE在处理语句群组时有相同的行为, scope of names, database context.
2. sp_executesql 其中的SQL语句直到被执行的时候才被编译. 语句的内容会被作为一个execution plan来编译和执行, 这个execution plan是与sp_executesql 的execution plan分开的.
3. sp_executesql的语句群组不能引用调用sp_executesql语句群组中的变量.
sp_executesql可以在仅仅是参数变化的情况下, 被用来替代stored procedure. 因为Transact-SQL语句本身是一个常量, 仅仅是参数变化, 这样SQL Server query optimizer就可以重用它第一次生成出来的execution plan.
例子:
MSDN上提供了很多例子. 这里贴一个我从profiler中抓出来的. 注意, 为了格式清晰, 我将sql语句进行了换行缩进整理.
DECLARE @p3 INT SET @p3=NULL EXEC Sp_executesql N' SELECT @has_access = CASE WHEN EXISTS (SELECT * FROM dbo.sysusers WHERE ( sid = Suser_sid(@user_name) ) AND ( hasdbaccess = 1 )) THEN 1 ELSE 0 END ', N'@has_access int output,@user_name nvarchar(128)', @has_access=@p3 OUTPUT, @user_name=N'DOMAIN1\User1' SELECT @p3
来源:
sp_executesql (Transact-SQL)