我使用以下脚本来获取所有数据库的行数 这些数据库的结构完全相同。
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#的运行时,根据我要比较的dbs数量来构建sql脚本,然后执行。
鉴于我想在同一台服务器上比较多个dbs的行 我似乎无法实现以下输出。我相信是我需要的支点 但似乎无法解决这个问题。
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
有关如何以上述格式退货的任何建议/帮助吗?
非常感谢。
答案 0 :(得分:0)
是。此时您需要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]
现在将结果作为数据库名称在行中的列和表名中进行。
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
编辑:
我已将数据插入临时表以便于理解。 CTE1
将csv转换为行,CTE2
从sys....
获取数据。在最后一部分中,我们使用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
现在声明变量以获取pivot
的列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