2017-03-03 17 views
2

我正在计划一个迁移并尝试获取我将从一台服务器迁移到另一台服务器的行数。我已经写了一个动态查询来保持超时,并且我不确定从服务器上的所有数据库获取行数的最佳方式,因为我们有超过500个数据库。我附上了我迄今为止编写的代码。来自所有SQL Server数据库的行数

DECLARE @sql NVARCHAR(MAX); 
DECLARE @ix INT = 1; 

DECLARE @temptbl TABLE (
dbname VARCHAR(500), 
cnt INT 
) 

DECLARE @dbs TABLE (
dbname NVARCHAR(500) 
) 
SET @sql = CAST(N'' AS NVARCHAR(MAX)); 
INSERT INTO @dbs 
    SELECT 
     Org_dbname 
    FROM [ourdatabases].dbo.tbl_datbases om 
    INNER JOIN sys.databases S 
     ON om.Org_dbname = S.name 
    WHERE Org_dbname IS NOT NULL 

; 


DECLARE @dbname VARCHAR(255) 

WHILE EXISTS (SELECT 
    * 
FROM @dbs) 
BEGIN 
SELECT TOP 1 
@dbname = dbname 
FROM @dbs 

PRINT @dbname 
SELECT 
@sql = @sql + N' 

use ' + QUOTENAME(@dbname) + '; 

     SELECT 

SUM(q1.[RowCount]) cnt 
FROM (SELECT 
     QUOTENAME(SCHEMA_NAME(sOBJ.schema_id)) + ''.'' +    QUOTENAME(sOBJ.name) AS [TableName] 
    ,SUM(sdmvPTNS.row_count) AS [RowCount] 
FROM sys.objects AS sOBJ 
INNER JOIN sys.dm_db_partition_stats AS sdmvPTNS 
    ON sOBJ.object_id = sdmvPTNS.object_id 
WHERE sOBJ.type = ''U'' 
AND sOBJ.is_ms_shipped = 0x0 
AND sdmvPTNS.index_id < 2 
GROUP BY sOBJ.schema_id 
     ,sOBJ.name) q1 

     ' 

DELETE FROM @dbs 
WHERE dbname = @dbname 

END 

SET @sql = STUFF(@sql, 1, 10, ''); 
PRINT @sql 

INSERT INTO @temptbl 

EXEC sp_executesql @sql 

SELECT 
    SUM(cnt) 
FROM @temptbl 
+0

难道你不想在输出中看到DBName和行数吗?你只有行数是无用的。 –

+0

@SeanLange目前整体计数很好,但显然你是对的我不会介意按数据库名称分组计数。 – VGJ

回答

1

你真的不需要游标,表变量或任何循环在这里。我们可以利用动态sql在所有数据库中生成全面的查询。以下是如何在您的实例上跨每个数据库执行此查询(有一些例外)。

declare @SQL nvarchar(max) = N''; 

select @SQL = @SQL + 
    N'SELECT DatabaseName = ''' + QUOTENAME(d.name) + N'''  
     ,SUM(sdmvPTNS.row_count) AS [RowCount] 
    FROM ' + QUOTENAME(d.name) + N'.sys.objects AS sOBJ 
    INNER JOIN ' + QUOTENAME(d.name) + N'.sys.dm_db_partition_stats AS sdmvPTNS 
     ON sOBJ.object_id = sdmvPTNS.object_id 
    WHERE sOBJ.type = ''U'' 
    AND sOBJ.is_ms_shipped = 0x0 
    AND sdmvPTNS.index_id < 2 UNION ALL ' 
from sys.databases d 
where name not in ('master', 'tempdb', 'model', 'msdb') 

set @SQL = left(@SQL, len(@SQL) - 10) --Need to remove the last UNION ALL 

--select @SQL 
exec sp_executesql @SQL 
+0

看起来非常干净整洁!也是一种魅力。谢谢 – VGJ

+0

很高兴为你工作。干杯! –

相关问题