我正在SQL Server中编写一些动态SQL。有几个查询合并为一个。第一个查询选择数据,第二个删除,第三个插入,最后一个删除临时表:
SET @completeSQL = @tempProdSQL + @deleteSQL + @insertSQL + ' DROP TABLE #tempProd'
PRINT(@completeSQL)
EXEC sp_ExecuteSQL @completeSQL
SET @archiveSize = @@ROWCOUNT
我知道我可以使用@@Rowcount
,但我的值为0.我相信这是因为最后一个命令是删除表。
在@tempProdSQL
命令之后有没有办法让行受影响?如果它会影响性能,我宁愿不将执行分开。
答案 0 :(得分:1)
<强>解释强>
在sp_executesql
的文档中,有一个&#34;备注&#34;部分说:
对于批处理,sp_executesql与EXECUTE具有相同的行为, 名称范围和数据库上下文。 Transact-SQL语句 sp_executesql stmt参数中的批处理或批处理直到 执行sp_executesql语句。然后是stmt的内容 作为与执行分开的执行计划编译和执行 调用sp_executesql的批处理的计划。 sp_executesql批处理 不能引用调用批处理中声明的变量 sp_executesql的。 sp_executesql批处理中的本地游标或变量 调用sp_executesql的批处理不可见。改变在 数据库上下文仅持续到sp_executesql语句的末尾。
另一种说法是因为动态SQL直到运行时才被编译,它被视为一个单独的批处理,并且在构建/执行它的过程之外有自己的上下文。
如果您利用sp_executesql
的其他参数,@params
和@param1
,您可以在动态SQL语句中找到@@row_count
,并传递该值回到主批/上下文。
<强>解决方案:强>
编辑:在@@rowcount
动态SQL之后立即移动@tempProdSQL
检查。
declare @row_cnt int --add this to your procedure's variables
set @completeSQL = @tempProdSQL + ' set @row_cnt_dyn = @@rowcount ' + @deleteSQL + @insertSQL + ' DROP TABLE #tempProd'
print (@completeSQL)
exec sp_executesql @completeSQL
, N'@row_cnt_dyn int out' --establishing the param in the dynamic sql batch
, @row_cnt_dyn = @row_cnt out --this is getting the value out of the dynamic batch into the main batch
set @archiveSize = @row_cnt
答案 1 :(得分:0)
您可以在@tempProdSQL之后立即捕获@@ rowcount的值,并使用输出参数将其返回到外部上下文:
SET @completeSQL = @tempProdSQL + '; SET @archiveSize1 = @@ROWCOUNT; ' + @deleteSQL + @insertSQL + ' DROP TABLE #tempProd'
PRINT(@completeSQL)
EXEC sp_executesql @completeSQL, N'@archiveSize1 INT OUTPUT', @archiveSize1 = @archiveSize OUTPUT
SELECT '@archiveSize:', @archiveSize