我正在尝试获取服务器中所有表的行数(不是特定数据库,而是服务器上的所有数据库,不包括 msdb、model、master 等)。除了数据库名称、表名称和行数之外,我不需要返回任何其他详细信息。
我解决这个问题的方法是获取服务器中的所有数据库并在它们上放置一个 id,这将在 while 循环中引用(从 id 开始直到最大 id)。然后,在 while 循环中,我获取匹配数据库 ID 中的表和行数。我的问题是 USE DatabaseName 似乎不允许我使其成为动态的,这意味着我不能将数据库名称存储在变量中,并在执行具有行计数查询的表时将其用作引用的数据库。
是否有另一种我缺少的方法(我查看了许多其他示例 - 经常使用游标,它在代码中似乎更长并且似乎使用更多资源 - 即使我使用,这也是一个相对快速的查询表中最大的数据库,除了它没有命中下一个数据库等等),还是我在代码中遗漏了一些明显的东西来使这个动态?
DECLARE @ServerTable TABLE(
DatabaseID INT IDENTITY(1,1),
DatabaseName VARCHAR(50)
)
DECLARE @count INT
DECLARE @start INT = 1
SELECT @count = COUNT(*) FROM sys.databases WHERE name NOT IN ('master','tempdb','model','msdb')
INSERT INTO @ServerTable (DatabaseName)
SELECT name
FROM sys.databases
WHERE name NOT IN ('master','tempdb','model','msdb')
WHILE @start < @count
BEGIN
DECLARE @db VARCHAR(50)
SELECT @db = DatabaseName FROM @ServerTable WHERE DatabaseID = @start
-- This is the problem, as the USE doesn't seem to allow it to be dynamic.
USE @db
GO
SELECT @db
,o.name [Name]
,ddps.row_count [Row Count]
FROM sys.indexes AS i
INNER JOIN sys.objects AS o ON i.OBJECT_ID = o.OBJECT_ID
INNER JOIN sys.dm_db_partition_stats AS ddps ON i.OBJECT_ID = ddps.OBJECT_ID AND i.index_id = ddps.index_id
WHERE i.index_id < 2 AND o.is_ms_shipped = 0
ORDER BY o.NAME
SET @start = @start + 1
END
注意:我尝试检查 sys.objects 和 sys.indexes 以查看是否可以使用数据库名称进行过滤,但我没有运气。
更新:我试着把它SELECT
变成动态的东西,但没有成功(注意下面的代码只显示了变化SELECT
):
SET @sql = '
SELECT ' + @db + ' [Database]
,o.name [Name]
,ddps.row_count [Row Count]
FROM ' + @db + '.sys.objects
INNER JOIN ' + @db + ' sys.objects AS o ON i.OBJECT_ID = o.OBJECT_ID
INNER JOIN ' + @db + ' sys.dm_db_partition_stats AS ddps ON i.OBJECT_ID = ddps.OBJECT_ID AND i.index_id = ddps.index_id
WHERE i.index_id < 2 AND o.is_ms_shipped = 0
ORDER BY o.NAME'