объединять базы данных по столбцам, где данные находятся в разных базах данных - PullRequest
0 голосов
/ 31 марта 2020

Я пытаюсь получить данные из таблиц, которые находятся в разных базах данных, но имеют одинаковую схему.

Имена баз данных IE будут выглядеть примерно так: DB1, DB2, DB3.

Все они содержат таблицу 'MyTable' и имеют внешний KEY, который соответствует первичному KEY 'MainTable' в БД, которую мы будем называть MainDB, я бы просто сделал объединение и позже позаботился о производительности. , но проблема, в данном конкретном случае, иногда в том, что DB3 (или любой из них) не существует, и это может привести к сбою моего запроса и необходимости его ежедневного редактирования.

MainTable имеет столбцы, которые в сочетании образуют имя БД, к которой нужно присоединиться в каждом столбце, для простоты я назову этот столбец с именем ForeignDBName. Я хочу что-то вроде

SELECT 
  MainPK
, FName
, LName
, BirthDate
, ForeignDBName
FROM
  MainDB.dbo.MainTable
LEFT JOIN
  (
   SELECT 
     BirthDate
    ,MainTableFK
   FROM
     DB1.dbo.MyTable
   UNION ALL
   SELECT 
     BirthDate
    ,MainTableFK
   FROM
     DB2.dbo.MyTable
   UNION ALL
   SELECT 
     BirthDate
    ,MainTableFK
   FROM
     DB3.dbo.MyTable
   ) B ON B.MainTableFK = MainPK

1 Ответ

0 голосов
/ 31 марта 2020

Поскольку вы не знаете, сколько баз данных вам действительно нужно, вам нужно запустить несколько динамических c SQL:

DECLARE @statement nvarchar(2048);
DECLARE @db_name varchar(128);
SET @statement='SELECT 
  MainPK
, FName
, LName
, BirthDate
, ForeignDBName
FROM
  MainDB.dbo.MainTable LEFT JOIN ('

DECLARE db_cursor CURSOR FOR 
--adjust database names here
select [name] from sys.databases where [name] in ('DB1','DB2','DB3','DB4','DB5')
ORDER BY name

OPEN db_cursor

FETCH NEXT FROM db_cursor INTO @db_name  

WHILE @@FETCH_STATUS = 0  
BEGIN  
    SET @statement=@statement+CHAR(10)+'SELECT BirthDate,MainTableFK FROM '+@db_name+'.dbo.MyTable UNION ALL ';
    FETCH NEXT FROM db_cursor INTO @db_name  
END
CLOSE db_cursor;
DEALLOCATE db_cursor;

-- we remove the last UNION ALL from the statement
SET @statement=LEFT(@statement,LEN(@statement) - 10)

SET @statement=@statement+') B ON B.MainTableFK = MainPK'

-- comment this to hide the statement that will be executed
print @statement;

--uncomment this if you want to actually execute the statement
--exec sp_executesql @statement
...