我正在尝试编写一个简单的存储过程,该过程需要三个参数“数据库名称一”,“数据库名称二”和“表名称”。然后,sql将对每个数据库中定义的表执行行计数并将其存储。
零星地处理它,我遇到了第一个问题,即您做不到
select * from @tablename
我知道您可以在exec命令中使用动态sql,但这并不理想,因为我无法返回值。
exec
下面的示例看起来像它应该工作,但是不起作用。
declare @tablename as nvarchar(500) declare @sqlstring as nvarchar(500) declare @parmdefinition as nvarchar(500) declare @numrows as bigint set @tablename = N'dummy_customer' set @parmdefinition = N'@tablenameIN nvarchar(500), @numrowsOUT as bigint OUTPUT' select @sqlstring = 'select @numrowsOUT = count(*) from @tablenameIN' select @sqlstring exec sp_executesql @sqlstring, @parmdefinition, @tablenameIN = @tablename, @numrowsOUT = @numrows OUTPUT select @numrows
给出的错误信息是
Msg 1087, Level 16, State 1, Line 1 Must declare the table variable "@tablenameIN".
当前正在使用SQL Server 2008 SP2。
编辑:之所以这样做是因为我们正在进行迁移,并且客户想要一个报告,该报告显示源数据库和目标数据库中每个表的行数。由于有许多表能够使用sp_MSForEachTable来调用存储的proc,因此似乎是理想的选择。
编辑:
最终的解决方案,以供将来参考
declare @tablename as nvarchar(500) declare @sqlstring as nvarchar(500) declare @parmdefinition as nvarchar(500) declare @numrows as bigint set @tablename = N'dummy_customers' set @parmdefinition = N'@tablename nvarchar(500), @numrowsOUT as bigint OUTPUT' select @sqlstring = 'select @numrowsOUT = count(*) from ' + quotename(@tablename) exec sp_executesql @sqlstring, @parmdefinition, @tablename = @tablename, @numrowsOUT = @numrows OUTPUT select @numrows
您必须使用动态sql,并将表名连接到SQL字符串中,然后才能通过sp_executsql执行:
select @sqlstring = 'select @numrowsOUT = count(*) from ' + QUOTENAME(@tablename) EXECUTE sp_executesql ....