我有一个TSQL sproc,它构建一个查询并执行它,如下所示:
EXEC (@sqlTop + @sqlBody + @sqlBottom)
@sqlTop包含类似SELECT TOP(x)col1,col2,col3 ......
的内容TOP(x)将限制返回的行,所以稍后我想知道表中的实际行数与查询匹配的是什么。
然后我用@sqlTop代替:EXEC ('SELECT @ActualNumberOfResults = COUNT(*) ' + @sqlBody)
我可以看出为什么这不起作用,以及为什么会出现未声明错误的值,但我认为它充分描述了我想要实现的目标。
有什么想法吗?
答案 0 :(得分:15)
您可以改为让动态查询将结果作为行集返回,然后使用INSERT ... EXEC
语法将其插入到表变量(也可以是临时表或普通表)中。然后,您可以使用SELECT @var = ...
:
DECLARE @rowcount TABLE (Value int);
INSERT INTO @rowcount
EXEC('SELECT COUNT(*) ' + @sqlBody);
SELECT @ActualNumberOfResults = Value FROM @rowcount;
答案 1 :(得分:13)
当天晚些时候,我发现this method更加简单:
-- test setup
DECLARE @sqlBody nvarchar(max) = N'SELECT MyField FROM dbo.MyTable WHERE MyOtherField = ''x''';
DECLARE @ActualNumberOfResults int;
-- the goods
EXEC sp_executesql @sqlBody;
SET @ActualNumberOfResults = @@ROWCOUNT;
SELECT @ActualNumberOfResults;
答案 2 :(得分:11)
使用sp_executesql
和output parameter
例如
DECLARE @sqlBody VARCHAR(500),@TableCount INT, @SQL NVARCHAR(1000)
SELECT @sqlBody = 'from sysobjects'
SELECT @SQL = N'SELECT @TableCount = COUNT(*) ' + @sqlBody
EXEC sp_executesql @SQL, N'@TableCount INT OUTPUT', @TableCount OUTPUT
SELECT @TableCount
GO
答案 3 :(得分:2)
执行实际查询后,将@@ROWCOUNT
的结果存储在以后可以使用的任何变量中。
EXEC sp_executesql 'SELECT TOP 10 FROM ABX'
SET @TotRecord = @@ROWCOUNT
到您的变量中供以后使用。
答案 4 :(得分:1)
请记住,动态SQL有自己的范围。声明/修改的任何变量都将超出EXEC
或sp_executesql
后的范围。
建议写入临时表,该临时表将在动态SQL语句的范围内,在外部。
也许把它放在sqlBottom
:
CREATE TABLE ##tempCounter(MyNum int);
EXEC('SELECT @ActualNumberOfResults = COUNT(*) ' + @sqlBody +
'; INSERT INTO ##tempCounter(MyNum) VALUES(@ActualNumberOfResults);');
SELECT MyNum FROM ##tempCounter;
答案 5 :(得分:0)
创建临时表(使用“DECLARE @rowcount TABLE”或“CREATE TABLE ## tempCounter(MyNum int)”)的答案的唯一问题是您必须将所有受影响的记录从磁盘读入记忆。如果你期望大量的记录,这可能需要一些时间。
因此,如果答案可能很大,那么“使用sp_executesql和输出参数”解决方案是一种更有效的答案。它似乎确实有用。
答案 6 :(得分:0)
您可以在 SP_EXECUTESQL 中使用输出变量
DECLARE @SQL NVARCHAR(MAX);
DECLARE @ParamDefinition NVARCHAR(100) = '@ROW_SQL INT OUTPUT'
DECLARE @AFFECTED_ROWS INT;
SELECT
@SQL = N'SELECT 1 UNION ALL SELECT 2'
SELECT @SQL += 'SELECT @ROW_SQL = @@ROWCOUNT;';
EXEC SP_EXECUTESQL @SQL, @ParamDefinition, @ROW_SQL=@AFFECTED_ROWS OUTPUT;
PRINT 'Number of affected rows: ' + CAST(@AFFECTED_ROWS AS VARCHAR(20));
输出:
SQL2.sql: Number of affected rows: 2
感谢耶稣费尔南德斯!