Получение данных из множества баз данных - база данных Dynami c - PullRequest
0 голосов
/ 12 июля 2020

Мы используем SQL Server 2014 Enterprise со многими базами данных. Мне нужно выполнить запрос и получить отчеты / данные из каждой базы данных с ТОЧНАЯ ТАКАЯ схема , а база данных начинается с Cab

Когда новая компания добавлен в наш проект ERP, новая база данных создается с точной схемой, начиная с Cab , и ей присваивается увеличенный номер, например:

Cab1
Cab2
Cab3
Cab5
Cab10

Я могу получить имена базы данных как:

SELECT name
FROM master.sys.databases
where [name] like 'Cab%' order by [name]

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

Как это сделать с помощью хранимой процедуры поскольку базы данных создаются динамически, начиная с Cab ?

Ответы [ 2 ]

0 голосов
/ 13 июля 2020

Быстрое и простое решение Dynami c SQL будет примерно таким:

DECLARE @Sql nvarchar(max);
SET @Sql  = STUFF((
    SELECT ' UNION ALL SELECT [ColumnsList], '''+ [name] + ''' As SourceDb FROM '+ QUOTENAME([name]) + '.[SchemaName].[TableName]' + char(10)
    FROM master.sys.databases
    WHERE [name] LIKE 'Cab%' 
    FOR XML PATH('')
), 1, 10, '');

--When dealing with dynamic SQL, print is your best friend...
PRINT @Sql

-- Once the @Sql is printed and you can see it looks OK, you can run it.
--EXEC(@Sql)

Примечания:

  1. Используйте кавычки для защиты от "смешных" символов в именах идентификаторов.
  2. Замените [ColumnsList] фактическим списком нужных столбцов.
  3. Нет необходимости в каких-либо циклах, просто stuff + for xml в mimi c string_agg (который был представлен только в 2017 году).
  4. Я добавил имя исходной базы данных в качестве «бонуса», если вы этого не хотите, это нормально.
  5. Предложение Order by в запросе, генерирующем динамику c SQL, не имеет смысла для окончательного запроса, поэтому я удалил его.
0 голосов
/ 12 июля 2020

Вы можете использовать EXE C (@ Statement) или EXE C SP_EXECUTE SQL, если вам нужно передать параметры.

CREATE OR ALTER PROCEDURE dbo.GetDataFromAllDatabases
AS
BEGIN
    DECLARE @T TABLE (id INT NOT NULL IDENTITY(1, 1), dbName VARCHAR(256) NOT NULL)
    INSERT INTO @T
    SELECT NAME FROM MASTER.SYS.DATABASES WHERE [NAME] LIKE 'Cab%' ORDER BY [NAME]

    CREATE TABLE #AllData (......)

    DECLARE @Id INT, @DbName VARCHAR(128)
    SELECT @Id = MIN(Id) FROM @T
    WHILE @Id IS NOT NULL
    BEGIN
        SELECT @DbName = dbName FROM @T WHERE Id = @Id
        DECLARE @Statement NVARCHAR(MAX)
        SET @Statement = CONCAT(N'INSERT INTO #AllData (...) SELECT .... FROM ', @DbName, '.dbo.[TableName]')
        EXEC(@Statement);
        --YOU CAN USE BELOW LINE TOO IF YOU NEED TO PASS VARIABLE
        --EXEC SP_EXECUTESQL @Statement, '@Value INT', @Value = 128
        SET @Id = (SELECT MIN(Id) FROM @T WHERE Id > @Id)
    END
END
...