一个表中的数据库列表,在一个SQL查询中从这些数据库查询表?

问题描述:

我在SQL 2005服务器上有很多数据库。 有一个名为'siteadmin'的主数据库,它有一个'PROJECTS'表,其中有一个列'DB_NAME'列出了其他数据库的名称。一个表中的数据库列表,在一个SQL查询中从这些数据库查询表?

我需要遍历每个数据库的名称,对每个数据库中存在的名为'BUG'的表执行count和max查询。

这是我想出了迄今为止最好的:

USE siteadmin 
DECLARE @dbname VARCHAR(50) 
DECLARE @iRowCount INT 
SET @iRowCount = 0 
WHILE @iRowCount < (SELECT COUNT(*) FROM PROJECTS) 

BEGIN 
    SELECT @dbname = DB_NAME FROM PROJECTS WHERE PROJECT_ID = @iRowCount 

    USE @dbname 
    select 
     SQ_SEQ_VALUE, 
     (select count(BG_BUG_ID) from td.BUG) TotalBUGs, 
     (select max(BG_BUG_ID) from td.BUG) MaxBUGID 
    from td.SEQUENCES 
    WHERE sq_seq_name='BUG' 

    SET @iRowCount = @iRowCount + 1 
    CONTINUE 
END 

它未能在“使用@dbname”语句。

每个数据库都有相同的'BUG'表,我需要获取最大错误ID和实际错误数量。 所以我需要一个像列表来结束:

 SQ_SEQ_VALUE, TotalBUGs, MaxBUGID 
dbname1 123   150  170 
dbname2 165   165  165 
dbname3 176   176  176 

我有一种感觉,我曾经在一个完全错误的方向走了。 有人能帮忙吗?

+0

`USE`需要一个真正的数据库名。它不能使用变量。不幸的是,这意味着你的代码中有一些动态的SQL。 – 2011-01-31 04:34:09

这看起来很奇怪,但我认为你有很好的理由。

如果您可以信任将存储在PROJECTS表的DB_NAME列中的值,则应该可以使用EXEC 'USE [' + @dbname + ']'替代切换活动数据库。

您必须确保用户有权从每个您需要连接的数据库中读取数据。可能有更好的方法来完成这个任务,但是对于你所拥有的我所期望的工作只需要很少的改变。

+0

我不得不使@RowCount = 1,并做你在()中所做的事情,现在它说它找不到'BUG'表,它肯定存在于每个数据库中。嗯... – 2011-01-31 01:36:30

这是我最后使用的代码:

USE siteadmin 
DECLARE @sqlq VARCHAR(1500) -- sql query 
DECLARE @dbname VARCHAR(100) -- database name 

DECLARE dbnamescursor CURSOR FOR SELECT DB_NAME FROM PROJECTS; 

OPEN dbnamescursor 
FETCH NEXT FROM dbnamescursor INTO @dbname 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    IF (db_id(@dbname) is not null) 
    BEGIN 

     SET @sqlq = 'SELECT ''' + @dbname + ''' as Databasename, Count([' + @dbname + '].[td.BUG].BG_BUG_ID) as TotalBUGs, Max([' + @dbname + '].[td.BUG].BG_BUG_ID) as MaxBUGID 
     FROM [' + @dbname + '].[td.BUG] CROSS JOIN [' + @dbname + '].SEQUENCES 
     WHERE ([' + @dbname + '].SEQUENCES.SQ_SEQ_NAME = ''BUG'') 
     GROUP BY [' + @dbname + '].SEQUENCES.SQ_SEQ_VALUE' 

     EXEC (@sqlq) 
    END 

    FETCH NEXT FROM dbnamescursor INTO @dbname 
END 

CLOSE dbnamescursor 
DEALLOCATE dbnamescursor