Sql server 2005 如何在SQLServer2005中循环访问多个数据库?

Sql server 2005 如何在SQLServer2005中循环访问多个数据库?,sql-server-2005,Sql Server 2005,我有大约50个不同的数据库,每个数据库中都有一个同名的表。现在,我编写了一个从表中提取选定字段的查询,但我需要手动选择数据库。如何编写查询以便传递数据库名称并从该表中提取数据? 这是我的密码: ;WITH Review as ( select external_id as sponsorid, name as sponsorname, memberid, startdate, paidamt, code from test.dev.sraw c left join client.dbo.sp

我有大约50个不同的数据库,每个数据库中都有一个同名的表。现在,我编写了一个从表中提取选定字段的查询,但我需要手动选择数据库。如何编写查询以便传递数据库名称并从该表中提取数据? 这是我的密码:

;WITH Review as (
select  external_id as sponsorid, name as sponsorname, memberid, startdate, paidamt, code
from  test.dev.sraw c left join client.dbo.sponsors s on c.customerid = s.external_id
where   year(startdate) >2009   and startdate <> '0001-01-01'   and startdate <> '1000-01-01'),

 FinalDataCollection as (select sponsorid,  sponsorname, count(*) as NbrOfClaims,  count(distinct memberid) as NbrOfMembers,  month(startdate) as mnth,  year(startdate) as yr,  sum(cast(paidamt as money)) as dollars, case when  code > '0' then 'RX' else 'med' end as category, case when  count(distinct memberid)> 0 then sum(cast(paidamt as money))/count(distinct memberid) else 0 end as costpm
 from Review
 group by sponsorid,  sponsorname,year(startdate), month(startdate),case when  code > '0' then 'RX' else 'med' end)

 select * from FinalDataCollection

谢谢

您可以创建一个具有一个参数@DbName的存储过程,因此:

结束

注:

分贝_ID@DbName不为NULL-它检查@DbName是否存在

@N'MyDB1',N'MyDB2',…,N'MyDBn'-中的DbName检查@DbName是否在允许数据库的白名单上。从这个角度来看,第一个检查是冗余的

我为什么用QUOTENAME@DbName ? 请参阅第节:如果@variable的内容是安全的,例如数据库/表,则建议使用包装器QUOTENAME@variable.

您可以将N'MyDB1',N'MyDB2',…,N'MyDBn'中的@DbName替换为exists,从而:

更新1:

你必须更换

从dbo.MyTable中选择t.Col1、t.Col2


阅读动态Sql以及在使用它时遇到的问题。你好Bogdan,我的select声明涉及CTE。我该怎么处理?谢谢你你必须换台…+N′;从dbo.MyTable'中选择t.Col1、t.Col2;使用您的查询集…+N′;使用CTE1。。。从dbo.CTE1'中选择t.Col1、t.Col2;嗨,博格丹,不知什么原因,我没能让它工作。我已经用我试图使之成为动态的代码修改了我原来的问题。请你回顾一下,并建议我如何使它可行。谢谢你,谢谢你,博格丹。这正在起作用。我真的很感激。我只是为这类事情创建了一个公共数据库。对我有用。
DECLARE @dbname NVARCHAR(200)
DECLARE @SQLString NVARCHAR (MAX)
SET @SQLString = 
'DECLARE @db NVARCHAR(255)
DECLARE DB_CURSOR  CURSOR LOCAL FAST_FORWARD FOR
        SELECT db.name from sys.databases db WHERE db.name  IN 
        (''A'',''B'',''C'' ) ORDER BY db.name
    OPEN DB_CURSOR
    FETCH NEXT FROM DB_CURSOR INTO @db
    WHILE @@FETCH_STATUS = 0
    BEGIN
        EXEC(''SELECT top 5 * FROM '' + @db + ''.dbo.RAW'')
        FETCH NEXT FROM DB_CURSOR INTO @db
    END
CLOSE DB_CURSOR
DEALLOCATE DB_CURSOR'
EXEC sp_executesql @SQLString
CREATE PROCEDURE dbo.GetDataFromMyTable (
@DbName SYSNAME -- or NVARCHAR(128)
)
AS
BEGIN
IF DB_ID(@DbName) IS NOT NULL AND @DbName IN (N'MyDB1', N'MyDB2', N'MyDB3', ...)
BEGIN 
    DECLARE @SqlStatement NVARCHAR(MAX);
    SET @SqlStatement = N'USE ' + QUOTENAME(@DbName) + N'; SELECT t.Col1, t.Col2 FROM dbo.MyTable';
    EXEC sp_executesql @SqlStatement;
END
ELSE
    RAISERROR('Wrong database.', 16, 1);
END
EXISTS (
    SELECT * 
    FROM ( 
        SELECT N'MyDB1' UNION ALL 
        SELECT N'MyDB2' UNION ALL 
        ...
        SELECT N'MyDBn'
    ) dbs(DbName)
    WHERE dbs.DbName = @DbName
)
WITH Review as (
select  external_id as sponsorid, name as sponsorname, memberid, startdate, paidamt, code
from  test.dev.sraw c left join client.dbo.sponsors s on c.customerid = s.external_id
where   year(startdate) >2009   and startdate <> ''0001-01-01''   and startdate <> ''1000-01-01''),

 FinalDataCollection as (select sponsorid,  sponsorname, count(*) as NbrOfClaims,  count(distinct memberid) as NbrOfMembers,  month(startdate) as mnth,  year(startdate) as yr,  sum(cast(paidamt as money)) as dollars, case when  code > ''0'' then ''RX'' else ''med'' end as category, case when  count(distinct memberid)> 0 then sum(cast(paidamt as money))/count(distinct memberid) else 0 end as costpm
 from Review
 group by sponsorid,  sponsorname,year(startdate), month(startdate),case when  code > ''0'' then ''RX'' else ''med'' end)

 select * from FinalDataCollection