我正在尝试从表列表中选择一个行计数,这些表在临时表中作为一列数据存在。我尝试使用游标来构建查询字符串,如下所示,但这不起作用,因为当我尝试执行该语句时,它无法引用在语句中先前声明的变量@Rows。
这是我尝试的第一个失败的方法,错误“必须声明标量变量@Rows”
SELECT @SQL = N'SELECT @Rows = @Rows + '
SELECT @SQL = @SQL + N'(SELECT COUNT(*) FROM [dbo].[' + @Table + '] '
SELECT @SQL = @SQL + N'WHERE tran_date < ' + CONVERT(VARCHAR(20), @Bound, 101) + ')'
然后我尝试了下面的内容,这也没有用,并且语法错误
失败了SELECT @SQL = N'(SELECT COUNT(*) FROM [dbo].[' + @Table + '] '
SELECT @SQL = @SQL + N'WHERE date < ' + CONVERT(VARCHAR(20), @Bound, 101) + ')'
SELECT @Rows = @Rows + EXEC(@SQL)
答案 0 :(得分:2)
使用* sp_executesql *将参数传递给动态sql
DECLARE @Rows BIGINT
SELECT @SQL = N'SELECT @Rows = @Rows + '
SELECT @SQL = @SQL + N'(SELECT COUNT(*) FROM [dbo].[' + @Table + '] '
SELECT @SQL = @SQL + N'WHERE tran_date < ' + CONVERT(VARCHAR(20), @Bound, 101) + ')'
EXEC sp_executesql N'@Rows BIGINT', @SQL, @Rows = @Rows OUTPUT
我也会将@Bound参数传递给sp_executesql过程:
DECLARE @Rows BIGINT
SELECT @SQL = N'SELECT @Rows = @Rows + '
SELECT @SQL = @SQL + N'(SELECT COUNT(*) FROM [dbo].[' + @Table + '] '
SELECT @SQL = @SQL + N'WHERE tran_date < @Bound)'
EXEC sp_executesql N'@Bound DATETIME, @Rows BIGINT OUTPUT', @SQL, @Bound = @Bound, @Rows = @Rows OUTPUT
因此,您可以获得缓存查询计划的好处
DavidW:
我遇到了一些语法错误,但下面的工作成功了。谢谢你指出我正确的方向
SELECT @SQL = N'(SELECT @RowsOut = COUNT(*) FROM [dbo].[' + @Table + '] '
SELECT @SQL = @SQL + N'WHERE tran_date < CONVERT(DATETIME,@BoundIn))'
PRINT 'SQL:' + @SQL + ' Bound: ' + CONVERT(VARCHAR(12),@Bound,101)
EXEC sp_executesql @SQL, N'@BoundIN SQL_VARIANT, @RowsOut INT OUTPUT', @BoundIn = @Bound, @RowsOut = @Rows OUTPUT