[英]Creating view from multiple databases linked by columns with db name
嗨,我需要创建一个视图或存储过程,该视图或存储过程将合并数据并使用保存模式(db)名称的列从同一服务器上的3个不同数据库返回结果集。
以第一个数据库为例,我有此表:
CREATE TABLE [dbo].[CloudUsers](
ID int IDENTITY(1,1) NOT NULL,
Username nvarchar(50) NULL,
MainDB nvarchar(100) NULL
) ON [PRIMARY]
每个CloudUser都有一个单独的数据库,因此接下来我需要使用MainDB名称从User数据库中获取数据。 我需要的数据总是1行,因为我正在使用聚合函数/查询。
因此,在User MainDB中,假设我有此表。
CREATE TABLE [dbo].[CLIENT](
ID int NOT NULL,
Name nvarchar(50) NULL,
ProjectDBName [nvarchar](100) NULL
CreationDate datetime NULL
) ON [PRIMARY]
我查询像:
select min(CreationDate) from MainDB.Client
对于客户端的相同想法,我需要从指向客户端ProjectDBName的第3个数据库中获取更多数据。 再次汇总数据:
select Count(id) as TotalTransactions from ProjectDBName.Journal
我的最终结果应该包含所有数据库的记录。 这是我需要统计的只读数据。
最终结果集示例:
CloudUsers.Username,MainDB-> CreationDate,ProjectDBName-> TotalTransaction
我该如何实现?
这并不容易-如果没有模式和示例数据,我将无法为您提供准确的答案。
您需要遍历每个客户端,并使用动态SQL对mainDB和projectDB联接执行查询。 您可以在一个巨大的“联合”查询中执行此操作,也可以通过创建一个临时表并将数据插入该临时表中,然后在查询结束时从临时表中进行选择来做到这一点。
对于对如何解决此问题感到好奇的您,我找到了自己的解决方案,其中使用了一些游标+动态表和一个简单的表变量,请尽情享受。
ALTER PROCEDURE CloudAnalysis as
DECLARE @objcursor cursor
DECLARE @innercursor cursor
DECLARE @userid int
,@maindb nvarchar(100)
,@clientid int
,@name nvarchar(50)
,@projdb nvarchar(100)
,@stat nvarchar(50)
,@sql nvarchar(max)
,@vsql nvarchar(max)
,@rowcount int
DECLARE @result table(userid int,clientid int,maindb nvarchar(100),name nvarchar(50),projdb nvarchar(100),stat nvarchar(50))
SET @objcursor = CURSOR FORWARD_ONLY STATIC FOR SELECT c.id,c.maindb,u.client_id FROM dbo.ClientUsers c join dbo.UserClients u on c.id = u.user_id open @objcursor
FETCH NEXT FROM @objcursor INTO @userid,@maindb,@clientid
WHILE (@@FETCH_STATUS=0)
BEGIN
IF (EXISTS (SELECT name
FROM master.dbo.sysdatabases
WHERE ('[' + name + ']' = @maindb
OR name = @maindb)))
BEGIN
set @sql = N'SELECT @name = c.name,@projdb=c.ProjectDBName FROM ' + @maindb + '.dbo.CLIENT c WHERE c.id = ' + cast(@clientid as nvarchar)
EXECUTE sp_executesql @sql, N'@name NVARCHAR(50) OUTPUT,@projdb NVARCHAR(100) OUTPUT',
@name = @name OUTPUT
,@projdb = @projdb OUTPUT
SELECT @rowcount = @@ROWCOUNT
IF @rowcount > 0
BEGIN
--print ' client: ' + cast(@clientid as nvarchar)+
--':' + @name + ' projdb: ' + @projdb
IF (EXISTS (SELECT name
FROM master.dbo.sysdatabases
WHERE ('[' + name + ']' = @projdb
OR name = @projdb)))
BEGIN
SET @sql = N'SELECT @stat = j.stat FROM ' + @projdb + '.dbo.JournalTransaction j'
EXECUTE sp_executesql @sql
,N'@stat NVARCHAR(50) OUTPUT'
,@stat = @stat OUTPUT
END
INSERT INTO @result (userid,clientid,maindb,name,projdb,stat)
VALUES (@userid,@clientid,@maindb,@name,@projdb,@stat)
END
END
FETCH NEXT FROM @objcursor INTO @userid,@maindb,@clientid
END
CLOSE @objcursor
DEALLOCATE @objcursor
SELECT * FROM @result
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.