如何从多个结构相同的数据库查询数据并返回记录所属的数据库名称
SQL Server多库同构表合并查询实现方案
方案1:少量固定数据库场景(静态写法)
如果待查询的数据库数量少且固定,直接用UNION ALL拼接各库查询逻辑即可,写法简单易维护:
SELECT X.Name1, X.Name2, 'database_A' AS [Current Database] FROM database_A.dbo.table1 A LEFT JOIN database_X.dbo.table_X X ON A.ID = X.ID_ID UNION ALL SELECT X.Name1, X.Name2, 'database_B' AS [Current Database] FROM database_B.dbo.table1 A LEFT JOIN database_X.dbo.table_X X ON A.ID = X.ID_ID UNION ALL SELECT X.Name1, X.Name2, 'database_C' AS [Current Database] FROM database_C.dbo.table1 A LEFT JOIN database_X.dbo.table_X X ON A.ID = X.ID_ID -- 新增数据库只需继续追加对应UNION ALL语句即可
方案2:大量/动态变化数据库场景(动态SQL写法)
如果待查询的数据库数量多、或者会频繁新增同结构数据库,可通过动态SQL自动遍历匹配的数据库生成查询语句,无需手动修改代码:
DECLARE @sql NVARCHAR(MAX) = N'' -- 遍历符合条件的数据库拼接查询逻辑 SELECT @sql += N'UNION ALL SELECT X.Name1, X.Name2, ''' + name + N''' AS [Current Database] FROM ' + QUOTENAME(name) + N'.dbo.table1 A LEFT JOIN database_X.dbo.table_X X ON A.ID = X.ID_ID ' FROM sys.databases WHERE -- 可自定义过滤条件,比如匹配前缀:name LIKE 'database_%' name IN ('database_A','database_B','database_C','database_D') AND state = 0 -- 仅查询状态正常的在线库 AND is_read_only = 0 -- 排除只读库,无需求可删除该行 -- 移除开头多余的UNION ALL关键字 SET @sql = STUFF(@sql, 1, 10, N'') -- 执行生成的动态SQL EXEC sp_executesql @sql
注意事项
- 执行SQL的账号需要具备所有待查询库
dbo.table1的读权限,以及固定关联库database_X.dbo.table_X的读权限 QUOTENAME函数不要随意删除,可避免库名包含特殊字符时执行报错- 动态SQL方案可灵活调整
sys.databases的过滤规则,适配不同的库名匹配需求
内容的提问来源于stack exchange,提问作者Karol karol
相关产品推荐
相关产品推荐

