SQL Cop - 测试所有数据库

时间:2014-02-11 18:06:07

标签: sql-server sql-server-2008 unit-testing

我们正在实现tSQLt作为我们的SQL单元测试框架。因此,我们也在研究SQL Cop。

我们有8个数据库。 SQL Cop很好用,因为它们是预构建的数据库检查。如果我们将tSQLt和SQL Cop添加到数据库,一切都很好。

但是,我们希望将SQL Cop测试分成TestAllDatabases数据库。

问题:有没有办法从这个能够检查我们所有8个数据库的数据库运行SQL Cop测试?

例如,在SQL Server上,我们可能有:

CustomerDB
InventoryDB

TestCustomerDB(保存tSQLt和所有针对CustomerDB运行的单元测试)
TestInventoryDB(保存tSQLt和所有针对InventoryDB运行的单元测试)
TestAllDatabasesDB(包含tSQLt和SQL Cop,但是我们需要SQL Cop来检查其他3个数据库。因为它只会在TestAllDatabasesDB数据库中运行检查。)

以下是SQL Cop的代码,它检查以'sp_%'开头的存储过程。 有没有办法修改此代码以对SQL Server上的所有数据库运行检查?例如,我们如何从TestAllDatabases运行它并让它检查CustomerDB?无论答案是什么,我们都可以重复此代码来检查InventoryDB。我们的想法是将所有SQL Cop代码放在一个位置,而不必在每个Testxxx数据库中复制代码。

SELECT  @Output = @Output + SPECIFIC_SCHEMA + '.' + SPECIFIC_NAME + Char(13) + Char(10)
From    INFORMATION_SCHEMA.ROUTINES
Where   SPECIFIC_NAME COLLATE SQL_LATIN1_GENERAL_CP1_CI_AI LIKE 'sp[_]%'
        And SPECIFIC_NAME COLLATE SQL_LATIN1_GENERAL_CP1_CI_AI NOT LIKE '%diagram%'
        AND ROUTINE_SCHEMA <> 'tSQLt'
Order By SPECIFIC_SCHEMA,SPECIFIC_NAME

提前致谢。

2 个答案:

答案 0 :(得分:2)

试试这个:

Create 
Table   #Temp(
            DBName VarChar(100), 
            CheckDate DateTime, 
            CheckName VarChar(100), 
            Results VarChar(100))

exec sp_msforeachdb '
If ''?'' Not In (''Master'',''Model'',''msdb'',''TempDB'')
Insert Into #Temp(DBName, CheckDate, CheckName, Results)
SELECT  ''?'' As DBName, 
        GetDate(), 
        ''SP Name'', 
        SPECIFIC_SCHEMA + ''.'' + SPECIFIC_NAME + Char(13) + Char(10)
From    [?].INFORMATION_SCHEMA.ROUTINES
Where   SPECIFIC_NAME COLLATE SQL_LATIN1_GENERAL_CP1_CI_AI LIKE ''sp[_]%''
        And SPECIFIC_NAME COLLATE SQL_LATIN1_GENERAL_CP1_CI_AI NOT LIKE ''%diagram%''
        AND ROUTINE_SCHEMA <> ''tSQLt''
Order By SPECIFIC_SCHEMA,SPECIFIC_NAME'

Select * From #Temp
Drop Table #Temp

如果将上面显示的代码复制/粘贴到查询窗口并运行它,您将看到它生成临时表并将SQLCop检查结果转储给它。从长远来看,我建议你在TestAllDatabasesDB中创建一个真实的表来存储这些信息。

请注意,代码将忽略4个系统数据库。如果您实际上将此数据库用作创建的新数据库的模型,则可能不希望忽略model数据库。

答案 1 :(得分:0)

谢谢G Mastros。你的代码很棒。我对它进行了修改,使其成为一个SQL测试,所有的错误过程都被收集并使用SQL Test很好地输出。

SET NOCOUNT ON

    DECLARE @Count INT
    DECLARE @Output VARCHAR(MAX)
    CREATE TABLE #Temp (
          DBName VARCHAR(100) ,
          CheckDate DATETIME ,
          CheckName VARCHAR(100) ,
          Results VARCHAR(100)
        )

    SET @Output = 'These proc names should not begin with SP_: ' + CHAR(13) + CHAR(10);

    EXEC sp_msforeachdb '
        If ''?'' Not In (''Master'',''Model'',''msdb'',''TempDB'')
        Insert Into #Temp(DBName, CheckDate, CheckName, Results)
        SELECT  ''?'' As DBName, 
                GetDate(), 
                ''SP Name'', 
                SPECIFIC_SCHEMA + ''.'' + SPECIFIC_NAME + Char(13) + Char(10)
        From    [?].INFORMATION_SCHEMA.ROUTINES
        Where   SPECIFIC_NAME COLLATE SQL_LATIN1_GENERAL_CP1_CI_AI LIKE ''sp[_]%''
                And SPECIFIC_NAME COLLATE SQL_LATIN1_GENERAL_CP1_CI_AI NOT LIKE ''%diagram%''
                AND ROUTINE_SCHEMA <> ''tSQLt''
        Order By SPECIFIC_SCHEMA,SPECIFIC_NAME'

    --SELECT  *
    --FROM    #Temp

    SELECT @Count = (SELECT COUNT(*) FROM #Temp);

    IF ( @Count > 0 ) 
        BEGIN -- run through cursor to grab all the violations
            DECLARE @DBName VARCHAR(50)
            DECLARE @Proc VARCHAR(50)               

            DECLARE error_cursor CURSOR FOR
            SELECT DBName, Results
            FROM #Temp

            OPEN error_cursor

            FETCH NEXT FROM error_cursor
            INTO @DBName, @Proc

            WHILE @@FETCH_STATUS = 0
            BEGIN
                SET @Output = @Output + ' ' + CHAR(13) + CHAR(10) + @DBName + '.' + @Proc;
                FETCH NEXT FROM error_cursor
                INTO @DBName, @Proc
            END

            CLOSE error_cursor
    DEALLOCATE error_cursor
            EXEC tSQLt.Fail @Output;

        END

    DROP TABLE #Temp