SQL Server - 仅显示包含数据的列

时间:2014-03-28 19:35:31

标签: sql sql-server

我需要创建一个报告,显示所有SSRS(rdl),指示报告使用的数据库。我使用了sys.databases和rdl内容来创建一个表,显示所有带有数据库名称作为列名的报表。 (客户端有超过100个数据库。)如果在rdl代码中找到了数据库,我用“X”表示它。

以下是一个例子:

Report Name      tempdb     Master   Test     Reports   Claims
My Report.rdl         X
Ur Report.rdl                           X           X
Master.rdl                                          X

目前我正在通过sys.databases进行while循环并创建一个动态SQL语句,如下所示:

...
    Declare variables

    Set @SQLStatement equal to the beginning of the select with static columns

...
  While Loop

    SET @ColumnsSqlStatement = 'SELECT @Result = Count(*) 
                                from ##DatabasesUsed where ['
                                + @NAME + '] = ''X'''

    EXEC sp_executesql @ColumnsSqlStatement, N'@Result int out',
        @NumberOfXs OUT

    IF @NumberOfXs > 0
        BEGIN
            SET @SQLStatement = @SQLStatement + ', DBU.['
                + LTRIM(RTRIM(@NAME)) + ']'
        END
  End Loop
然后我执行@SQLStatement,它只返回带数据的列。

 Report Name      tempdb     Test     Reports  
 My Report.rdl         X
 Ur Report.rdl                  X           X
 Master.rdl                                 X

我正在寻找一个基于集合的解决方案来摆脱while循环。像这样:

SELECT E.Name AS [Database],
(
    SELECT Count(*) FROM ##DatabasesUsed WHERE [E.Name] = 'X'
) AS [counts] 
FROM sys.databases E

显然这不起作用,但我需要的是选择将E.Name转换为E.Name的值。

我感谢任何帮助。也许我的问题有一个完全不同的解决方案。

感谢。

1 个答案:

答案 0 :(得分:0)

尝试这个...我正在使用所有临时表,因此您需要对其中的一些进行改进以匹配您的数据库表(您应该能够复制并粘贴它并让它运行得很好但是用于测试管他呢)。我也有一些调试SELECT语句,只是为了显示输出。我希望这有帮助!

IF OBJECT_ID('tempDB..#DBsUsed') IS NOT NULL
    DROP TABLE #DBsUsed
CREATE TABLE #DBsUsed (REPORT_NAME VARCHAR(50), tempDb VARCHAR, [Master] VARCHAR, Test VARCHAR, Reports VARCHAR, Claims VARCHAR)
INSERT INTO #DBsUsed (REPORT_NAME, tempDb, Master, Test, Reports, Claims)
VALUES
    ('My Report.rdl', 'X', '', '', '', ''),
    ('Your Report.rdl', '', '', 'X', 'X', ''),
    ('Master.rdl', '', '', '', 'X', '')
SELECT *
FROM #DBsUsed
IF OBJECT_ID('tempDB..#Temp_Columns') IS NOT NULL
    DROP TABLE #Temp_Columns
CREATE TABLE #Temp_Columns (COLUMN_NAME VARCHAR(50), HasData INT, SQLCommand VARCHAR(MAX))
INSERT INTO #Temp_Columns (COLUMN_NAME, HasData, SQLCommand)
SELECT name, NULL, 'WHEN ''' + name + ''' THEN (SELECT COUNT(*) FROM #DBsUsed WHERE ' + name + '=''X'')'
FROM tempDB.sys.columns
WHERE [object_id] = OBJECT_ID('tempDB..#DBsUsed')
    AND name <> 'REPORT_NAME'

SELECT *
FROM #Temp_Columns;

DECLARE @MasterCommand VARCHAR(MAX) = ( 'UPDATE #Temp_Columns SET HasData = CASE COLUMN_NAME ' + (SELECT SQLCommand + ' ' FROM #Temp_Columns FOR XML PATH('')) + ' END')
EXEC (@MasterCommand)

SELECT *
FROM #Temp_Columns

DELETE FROM #Temp_Columns
WHERE HasData = 0

DECLARE @ColumnList VARCHAR(MAX), @FinalSelect VARCHAR(MAX) 
SET @ColumnList = (SELECT COLUMN_NAME + ',' FROM #Temp_Columns FOR XML PATH (''))
SET @ColumnList = LEFT(@ColumnList, LEN(@ColumnList) - 1)
SET @FinalSelect = 'SELECT ' + @ColumnList + ' FROM #DBsUsed'
EXEC (@FinalSelect)

最后一行(EXEC(@FinalSelect))应该可以获得您正在寻找的输出。