您好我需要创建一个视图或存储过程,它结合数据并使用包含模式(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
客户端的相同想法我需要从指向Client ProjectDBName的第3个数据库中获取更多数据。它再次是汇总数据:
select Count(id) as TotalTransactions from ProjectDBName.Journal
我的最终结果应该包含所有数据库的记录。这是统计数据所需的只读数据。
最终结果集示例:
CloudUsers.Username,MainDB-> CreationDate,ProjectDBName-> TotalTransaction
我怎样才能做到这一点?
答案 0 :(得分:0)
这并不容易 - 如果没有架构和示例数据,我无法给出准确的答案。
您需要遍历每个客户端,并使用dynamic SQL执行针对mainDB和projectDB连接的查询。您可以在一个巨大的“联合”查询中执行此操作,也可以通过创建临时表并将数据插入该临时表,然后从查询末尾的临时表中进行选择。
答案 1 :(得分:0)
对于那些对如何解决这个问题感到好奇的人,我找到了自己的解决方案,使用了一些游标+动态和一个简单的表变量,享受。
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