2013-08-27 28 views
24

我有(用于测试目的)在sql server 2008 r2实例上具有相同模式(=基本上相同的表和列)的许多dbs。如何在实例上的所有数据库上运行相同的查询?

我想喜欢

SELECT COUNT(*) FROM CUSTOMERS 

上的实例中的所有数据块的查询。我想有作为的结果2列:

1 - 数据库名称

2 - COUNT(*)

例中的价值:

DBName // COUNT (*) 

TestDB1 // 4 

MyDB // 5 

etc... 

注意:CUSTOMERS表存在我承担在所有dbs中(master除外)。

回答

31

尝试这一个 -

SET NOCOUNT ON; 

IF OBJECT_ID (N'tempdb.dbo.#temp') IS NOT NULL 
    DROP TABLE #temp 

CREATE TABLE #temp 
(
     [COUNT] INT 
    , DB VARCHAR(50) 
) 

DECLARE @TableName NVARCHAR(50) 
SELECT @TableName = '[dbo].[CUSTOMERS]' 

DECLARE @SQL NVARCHAR(MAX) 
SELECT @SQL = STUFF((
    SELECT CHAR(13) + 'SELECT ''' + name + ''', COUNT(1) FROM [' + name + '].' + @TableName 
    FROM sys.databases 
    WHERE OBJECT_ID(name + '.' + @TableName) IS NOT NULL 
    FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') 

INSERT INTO #temp (DB, [COUNT])    
EXEC sys.sp_executesql @SQL 

SELECT * 
FROM #temp t 

输出(例如,在AdventureWorks) -

COUNT  DB 
----------- -------------------------------------------------- 
19972  AdventureWorks2008R2 
19975  AdventureWorks2012 
19472  AdventureWorks2008R2_Live 
+0

嗨Devart,我使用这个SQL和伟大的工程。但是,如果运行此查询的用户能否访问每个数据库,是否可以添加检查,如果不是,则查询仍应继续运行,并只返回用户有权访问的数据库。我所追求的是用户是否对每个数据库拥有DBO角色权限,如果不移动到下一个数据库上,请您提供建议。 – DK2014

23

直截了当查询

EXECUTE sp_MSForEachDB 
     'USE ?; SELECT DB_NAME()AS DBName, 
     COUNT(1)AS [Count] FROM CUSTOMERS' 

这个查询会告诉你你想看到什么,但也将引发对每个数据库错误,而所谓的“顾客”表。你将需要制定一个逻辑来处理这个问题。

拉吉

+1

+1这是一个非常紧凑的解决方案,但我cho另一个是因为你的解决方案包含许多结果表,而另一个不是 – LaBracca

+3

可能值得一提的是,sp_MSForEachDB没有记录,不受支持,并且有一些已知问题,如Aaron Bertrand在这里http://sqlblog.com/blogs/aaron_bertrand /archive/2010/12/29/a-more-reliable-and-more-flexible-sp-msforeachdb.aspx。 –

5

怎么是这样的:

DECLARE c_db_names CURSOR FOR 
SELECT name 
FROM sys.databases 
WHERE name NOT IN('master', 'tempdb') --might need to exclude more dbs 

OPEN c_db_names 

FETCH c_db_names INTO @db_name 

WHILE @@Fetch_Status = 0 
BEGIN 
    EXEC(' 
    INSERT INTO #report 
    SELECT 
     ''' + @db_name + ''' 
     ,COUNT(*) 
    FROM ' + @db_name + '..linkfile 
    ') 
    FETCH c_db_names INTO @db_name 
END 

CLOSE c_db_names 
DEALLOCATE c_db_names 

SELECT * FROM #report 
+0

这是一个有用的通用代码片段,我用'sys.tables'替换了'sys.databases',用于完全不同的目的,使用相同的样板。 –

+2

你已经忘记在脚本中声明[at] db_name,你需要添加一行:DECLARE @db_name NVARCHAR(150),否则非常有用的脚本:-) – inkubpl

+0

临时表在哪里被删除? – Phil3992

相关问题