MSSQL 提供的两种动态执行SQL语句的命令:EXEC 和 sp_executesql。
EXEC:
一种是执行一个存储过程: EXEC procedure_name
另一种是执行一个动态的批处理:
DECLARE @TableName VARCHAR(50),@Sql NVARCHAR(MAX),@OrderID INT;
SET @TableName = 'Orders';
SET @OrderID = 10251;
SET @sql = 'SELECT * FROM '+QUOTENAME(@TableName) +'WHERE OrderID = '+CAST(@OrderID AS VARCHAR(10))+' ORDER BY ORDERID DESC'
EXEC(@sql); ( exec sp_executesql @sql )
注意:1.EXEC括号中只允许包含一个字符串变量,但是可以串联多个变量,如 EXEC(@sql+@sql2+@sql3);
2.不能执行一个包含一个带变量符的批处理,如将CAST(@OrderID AS VARCHAR(10)) 改成@OrderID 报错。
3.不支持动态批处理中的输入参数外,他也不支持输出参数
DECLARE @sql NVARCHAR(MAX),@RecordCount INT
SET @sql = 'SELECT COUNT(ORDERID) FROM Orders';
CREATE TABLE #T(TID INT);
INSERT INTO #T EXEC(@sql);
SET @RecordCount = (SELECT TID FROM #T)
SELECT @RecordCount
DROP TABLE #T
sp_executesql:支持输入参数和输出参数。构成包括:代码快,参数声明部分,参数赋值部分。
EXEC sp_executesql
@stmt = <statement>,--类似存储过程主体
@params = <params>, --类似存储过程参数部分
<params assignment> --类似存储过程调用
@stmt参数是输入的动态批处理,它可以引入输入参数或输出参数,和存储过程的主体语句一样,只不过它是动态的,而存储过程是静态的,不过你也可以在存储过程中使用sp_executesql;
@params参数与定义输入/输出参数的存储过程头类似,实际上和存储过程头的语法完全一样;
@<params assignment> 与调用存储过程的EXEC部分类似。
为了说明sp_executesql对执行计划的管理优于EXEC,我将使用前面讨论EXEC时用到的代码。
1: DECLARE @TableName VARCHAR(50),@sql NVARCHAR(MAX),@OrderID INT;
2: SET @TableName = 'Orders ';
3: SET @OrderID = 10251;
4: SET @sql = 'SELECT * FROM '+QUOTENAME(@TableName) + ' WHERE OrderID = @OID ORDER BY ORDERID DESC'
5: EXEC sp_executesql
6: @stmt = @sql,
7: @params = N'@OID AS INT ',
8: @OID = @OrderID
橙色部分 与 exec 的区别。
DECLARE @sql AS NVARCHAR(12),@i AS INT;
SET @sql = N' SET @p = 10';
EXEC sp_executesql
@stmt = @sql,
@params = N'@p AS INT OUTPUT',
@p = @i OUTPUT
SELECT @i
区别:不需要建立临时表存储输出结果。