查询同一服务器上的多个数据库

时间:2016-05-03 09:33:16

标签: sql-server database

我需要查询服务器上的所有数据库。我浏览了所有数据库并将每个数据库分配给变量@DB

然后我可以通过从游标中执行SQL来使用@DB,这一切都很好,直到我需要做另一个,如果存在来处理不包含我需要检查的状态的数据库。代码如下。

谢谢,

set nocount on
use [master]
declare @DB sysname
declare @sql nvarchar(max)
declare curDB cursor for
select [name] from sysdatabases
order by name


create table #results (
[Database] nvarchar(max),
[CompanyCode] nvarchar(max),
[Title] nvarchar(max),
[Status] nvarchar(max)
)

use [master]
open curDB
fetch next from curDB into @DB
while @@FETCH_STATUS=0
begin

set @sql = 'use [' + @DB + ']; if exists(select 1 from sys.tables where name=''Licence'')
begin

Insert into #results
Select
DB_NAME() as ''Databas'',
Company as ''CompanyCode'',
Title as ''Title''
'


use @DB; --This is what i'm struggling with because the if exists check below is checking against master, i need it to check the current @DB from curDB
if exists (select 'X' from sys.columns where name = 'DocumentLevelInvoiceMatching')

    begin
        set @sql = @sql + 'Case when Status = 1 then ''NewEngine'' else ''OldEngine'' end as ''MatchingEngine''
        from dsdba.companies
        end
        '
    end
else
    set @sql = @sql + '''Old Engine''
    from dsdba.companies
    end
    '


use master
exec (@sql)
fetch next from curDB into @DB
end

use CentralDatabase

IF OBJECT_ID('dbo.CompanyConfiguration', 'U') IS NOT NULL 
  DROP TABLE dbo.CompanyConfiguration; 

use master
select * into CentralDatabase.dbo.CompanyConfiguration
from #results

Select * from CentralDatabase.dbo.CompanyConfiguration
close curDB
deallocate curDB


drop table #results

2 个答案:

答案 0 :(得分:0)

您可以将支票移至dynamic SQL

示例

DECLARE @Qry NVARCHAR(MAX) = '
    USE ' + QUOTENAME(@DB) + ';

    IF EXISTS (SELECT 1 FROM sys.columns...) 
        BEGIN
            ...
        END
    ELSE
        BEGIN
            ...
        END
';

EXECUTE(@Qry);

USE不能与动态sql之外的变量组合,使语句USE @DB无效。这是因为@DB是一个字符串(NVARCHAR(128)),而USE需要一个数据库。遗憾的是,您无法直接对数据库进行参数化。

我添加了功能QUOTENAME来帮助防止SQL injection攻击。

答案 1 :(得分:0)

USE @DatabaseName

可以从动态EXECUTE语句发出,但它只会在你所做的语句的上下文中生效(参见How can I do something like: USE @databaseName

在您的情况下,您可以执行以下操作:

DECLARE @exists BIT=0,
@tempSQL NVARCHAR(100)='use '+@DB+'; select @exists=''1'' from sys.columns where name = ''DocumentLevelInvoiceMatching''';

EXECUTE sp_executesql @tempSQL, N'@exists BIT OUTPUT', @exists OUTPUT;
PRINT @exists;

然后测试@exists的值