获取 dbs 和 pivot sql server 2012 中所有表的行数

Get row count for all tables across dbs and pivot sql server 2012

我正在使用以下脚本获取所有数据库的行数 这些数据库在结构上都是相同的。

USE [MyTestDb1];

SELECT 
    'MyTestDb1'as [Database Name], so.name AS [Table Name],   
    rows AS [RowCount]   
FROM 
    sysindexes AS si   
JOIN 
    sysobjects AS so on si.id = so.id   
WHERE 
    indid IN (0,1)   
    AND xtype = 'U'

USE [MyTestDb2];

SELECT 
   'MyTestDb2'as [Database Name], so.name AS [Table Name],   
    rows AS [RowCount]   
FROM 
    sysindexes AS si   
JOIN 
    sysobjects AS so on si.id = so.id   
WHERE 
    indid IN (0,1)  
    AND xtype = 'U'

在 运行 从 c# 开始,我构建了 sql 脚本,具体取决于我比较的数据库数量,然后执行。

考虑到我想比较同一台服务器上多个数据库的行 我似乎无法实现以下 output.I 相信这是我需要的支点 但似乎无法解决。

TableName   Db1     Db2   Db3    Db4
------------------------------------
Table1      10      10    10     10
Table2      13      13    13     13
Table3      10      10    10     10
Table4      10      10    10     10
Table5      10      10    10     10

关于如何return以上格式的任何suggestion/help?

非常感谢。

是的。此时您需要PIVOT

首先声明一个变量动态获取列名

DECLARE @cols NVARCHAR (MAX)

SELECT @cols = COALESCE (@cols + ',[' + [Database Name] + ']', '[' + [Database Name] + ']')
               FROM    
               (
                    SELECT DISTINCT 'MyTestDb1'as [Database Name]   
                    FROM sysindexes AS si   
                        join sysobjects AS so on si.id = so.id   
                    WHERE indid IN (0,1)   
                    AND xtype = 'U'
                ) PV 
               ORDER BY [Database Name]

现在将结果转换为列中的数据库名称和行中的 table 名称。

DECLARE @query NVARCHAR(MAX)
SET @query = '-- This outer query forms your pivoted result
             SELECT * FROM 
             (
                SELECT ''MyTestDb1'' as [Database Name], so.name AS [Table Name],   
                rows AS [RowCount]   
                FROM sysindexes AS si   
                    join sysobjects AS so on si.id = so.id   
                WHERE indid IN (0,1)   
                AND xtype = ''U''
             ) x
             PIVOT 
             (
                 --Defines the values in each dynamic columns
                 MIN([RowCount])
                 -- Get the names from the @cols variable to show as column
                 FOR [Database Name] IN (' + @cols + ')
            ) p            
            ORDER BY [Table Name];' 

EXEC SP_EXECUTESQL @query

编辑:

为了便于理解,我已经将数据插入到临时table中。 CTE1 将 csv 转换为行,CTE2sys.... 获取数据。在最后一部分,我们使用 CROSS JOIN 因为根据您的要求不需要 INNER JOIN

DECLARE @PARAM VARCHAR(MAX)='DB1 | DB2 | DB3'

;WITH CTE1 AS
(
    SELECT LTRIM(RTRIM(Split.a.value('.', 'VARCHAR(100)'))) 'Database Name' 
    FROM  
    (         
         SELECT CAST ('<M>' + REPLACE(@PARAM, '|', '</M><M>') + '</M>' AS XML) AS Data              
    ) AS A 
    CROSS APPLY Data.nodes ('/M') AS Split(a)
)
,CTE2 AS
(
    SELECT so.name AS [Table Name],   
        rows AS [RowCount]   
    FROM sysindexes AS si   
        join sysobjects AS so on si.id = so.id   
    WHERE indid IN (0,1)   
    AND xtype = 'U'
)
SELECT [Database Name],[Table Name],[RowCount]
INTO #NEWTABLE
FROM CTE1 
CROSS JOIN CTE2

现在声明变量以获取数据透视表的列

DECLARE @cols NVARCHAR (MAX)

SELECT @cols = STUFF((SELECT distinct ',' + QUOTENAME(DatabaseName) 
            FROM 
            (
                SELECT LTRIM(RTRIM(Split.a.value('.', 'VARCHAR(100)'))) 'DatabaseName' 
                FROM  
                (         
                     SELECT CAST ('<M>' + REPLACE(@PARAM, '|', '</M><M>') + '</M>' AS XML) AS Data              
                ) AS A 
                CROSS APPLY Data.nodes ('/M') AS Split(a)
            ) c
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

现在转向查询

DECLARE @query NVARCHAR(MAX)
SET @query = '
SELECT * 
FROM
(
    SELECT [Database Name],[Table Name],[RowCount]
    FROM #NEWTABLE  
)TAB
PIVOT 
(
     MIN([RowCount])
     for [Database Name] in (' + @cols + ')
) as P' 

EXEC SP_EXECUTESQL @query