Запрос нескольких баз данных на одном сервере

Мне нужно запросить все базы данных на сервере. I наведите курсор на все базы данных и назначьте каждой следующей переменной @DB

Затем я могу использовать @DB, выполняя SQL из курсора, и это все нормально, пока мне не нужно сделать еще один, если существует, чтобы обрабатывать базы данных, которые не содержат статус, который мне нужно проверить. Код ниже.

Спасибо,

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 ответа

  1. Вы можете переместить проверку в динамический SQL .

    Образец

    DECLARE @Qry NVARCHAR(MAX) = '
        USE ' + QUOTENAME(@DB) + ';
    
        IF EXISTS (SELECT 1 FROM sys.columns...) 
            BEGIN
                ...
            END
        ELSE
            BEGIN
                ...
            END
    ';
    
    EXECUTE(@Qry);
    

    Использование не может быть объединено с переменной вне динамического sql, что делает оператор USE @DBнедопустимым. Это связано с тем, что @DB является строкой (NVARCHAR (128)) и USE ожидает базу данных. К сожалению, вы не можете непосредственно параметризовать базы данных.

    Я добавил имя функции QUOTON, чтобы предотвратить атаки SQL-инъекций.

  2. Этот

    USE @DatabaseName
    

    может быть выдан из динамического оператора EXECUTE, но тогда он будет иметь эффект только в контексте сделанного вами оператора (см. Как я могу сделать что-то вроде: использовать @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