2017-03-03 1 views
2

Ich plane eine Migration und versuche, eine Anzahl von Zeilen zu erhalten, wie viele Zeilen ich von einem Server auf einen anderen migrieren werde. Ich habe eine dynamische Abfrage geschrieben, die das Timing ausschaltet, und ich bin mir nicht sicher, ob es am besten ist, eine Zeilenanzahl aus allen Datenbanken auf dem Server zu erhalten, da wir über 500 Datenbanken haben. Ich füge den Code unter dem, den ich bisher geschrieben habe.Zeilenanzahl aus allen SQL Server-Datenbanken

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

Möchten Sie nicht den DBName UND die Zeilenanzahl in Ihrer Ausgabe sehen? Sie haben nur die rowcount, die von sich selbst nutzlos ist. –

+0

@SeanLange Gegenwärtig ist eine Gesamtzählung in Ordnung, aber offensichtlich hast du recht, ich hätte nichts dagegen, die Anzahl nach Datenbanknamen zu gruppieren. – VGJ

Antwort

1

Sie brauchen hier wirklich keinen Cursor, keine Tabellenvariable oder irgendeine Schleife. Wir können dynamic sql nutzen, um eine umfassende Abfrage für alle Datenbanken zu generieren. Hier ist, wie Sie diese Abfrage für jede Instanz (mit einigen Ausnahmen) auf Ihrer Instanz ausführen können.

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

Das sieht so viel sauberer und ordentlicher aus! Funktioniert auch ein Charme. Danke – VGJ

+0

Froh, dass das für dich funktioniert hat. Prost! –