Query across multiple databases on same server

Viewed 146429

I am looking for a way of dealing with the following situation:

  1. We have a database server with multiple databases on it (all have the same schema, different data).

  2. We are looking for a way to query across all the databases (and for it to be easy to configure, as more databases may be added at any time). This data access must be realtime.

Say, as an example, you have an application that inserts orders - each application has its own DB etc. What we are then looking for is an efficient way for a single application to then access the order information in all the other databases in order to query it and subsequently action it.

My searches to date have not revealed very much, however I think I may just be missing the appropriate keywords in order to find the correct info...

5 Answers

Note - My answer below received a couple down votes, but only one comment giving any reason why it might be down-voted. The comment was that this answer is very similar to the accepted answer, but even less performant. I disagree with this opinion and I reproduce my response here - in the actual answer - so that anyone else reading my answer might have a better chance at seeing why this is not the same as the accepted answer at all, and in fact better addresses the original question.

My response to the suggestion this is similar to the accepted answer:

on the contrary - the original question notes that new databases are added regularly. The accepted solution will require maintenance each time a new database is added. The solution here will work regardless of whether any new databases are added (in line with the original question that states they all have the same schema). Further, the accepted answer requires you to duplicate the query once per database queried. If the query is complex, that gets ugly fast. The proposal here ensures a single source of truth for the logic being used in the query.

And the answer itself:

Shooting from the hip here.

use master;
go

create table #Temp (sourceDBName varchar(128), colA varchar(128), colB varchar(128));

exec sp_MSforeachDB ' USE [?];

insert into #Temp
SELECT DISTINCT
 ''?'',
tableA.colA,
tableB.colB
FROM tableA JOIN tableB on some_conditions
WHERE someCol LIKE ''%some_term%''
'

select sourceDBName, colA, colB from #Temp order by 1, 2, 3;

drop table #Temp;

This logic should allow you to apply a single query to all databases. To use it though, you will want to add logic to filter out system databases, or explicitly include only the databases you specify. To achieve that, you might like to put this logic into a stored procedure which then returns a result set, so in the end, your call to this logic is a select statement that returns a rowset you can join, filter, etc.

Check out https://www.mssqltips.com/sqlservertip/2855/sql-server-multi-database-query-with-registered-servers/

SELECT * FROM (
SELECT 
    @@SERVERNAME as [ServerName],
    @@version [Version],
    Format(@@CONNECTIONS,'N0') [Conections],
    Format(@@CPU_BUSY ,'N0')[CPUBusy]
) SQLInfo
LEFT JOIN (
    SELECT 
        @@SERVERNAME AS [ServerName],
        SERVERPROPERTY('ProductVersion') [Version Build],
        SERVERPROPERTY ('Edition') AS [Edition],
        SERVERPROPERTY('ProductLevel') AS [Service Pack],
        CASE SERVERPROPERTY('IsIntegratedSecurityOnly') 
         WHEN 0 THEN 'SQL Server and Windows Authentication mode'
         WHEN 1 THEN 'Windows Authentication mode'
        END AS [Server Authentication],
        CASE SERVERPROPERTY('IsClustered') 
         WHEN 0 THEN 'False'
         WHEN 1 THEN 'True'
        END AS [Is Clustered?],
        SERVERPROPERTY('ComputerNamePhysicalNetBIOS') AS [Current Node Name],
        SERVERPROPERTY('Collation') AS [ SQL Collation],
        [cpu_count] AS [CPUs],
        [physical_memory_kb]*0.00000095367432 AS [RAM (GB)]
    FROM [sys].[dm_os_sys_info]
) SQLInfo2 on SQLInfo.[ServerName]=SQLInfo2.[ServerName]
LEFT JOIN (
    SELECT 
        @@SERVERNAME as [ServerName],
        NodeName,
        Status_Description,
        is_Current_Owner
    FROM [MASTER].[sys].[fn_virtualservernodes]()
)Clusterinfo on SQLInfo.[ServerName]=Clusterinfo.[ServerName]
Related