我们正在实现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
提前致谢。
答案 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