SQL Server跨数据库查询时,其他数据库名称事先不知道?

时间:2010-09-14 08:11:46

标签: sql-server multi-tenant cross-database

如果多租户设置包含一个保存租户数据的数据库,并且每个租户都有一个数据库,那么如何构建查询以在每个租户数据库中查找相同的数据?

例如租户主数据库有一个名为Tenants的表:

[TenantMaster].[dbo].[Tenants]
Id, Name, DatabaseName
1, Bob, bobs_db_name
2, Kate, kates_db_name

每个租户都有一个名为Widgets的表:

[bobs_db_name].[dbo].[Widgets]
Id, Name
1, Red widget

是否可以编写一个select查询来获取每个租户数据库中的小部件数量?还是需要游标或存储过程?例如输出将是:

Tenant, WidgetCount
Bob, 10
Kate, 12

3 个答案:

答案 0 :(得分:2)

在多租户设置中,我建议考虑在中央数据库中缓存这些“全面”统计数据并定期更新

e.g。主表中的表格,包含以下列:
TenantId

widgetCount的 AsOfDate

这样,您可以非常快速地查询统计数据而无需点击每个数据库(但显然数据可能已过期,具体取决于更新的频率)。

对于多租户系统中的扩展,我推荐这种方法。但它确实依赖于(一如既往)确切的要求/是否可以使用稍微过时的统计数据等。

答案 1 :(得分:2)

     create table #TenatsWidjetCount 
     (
      TenantID int,
      TenantName nvarchar(100),
      Count int 
      )

     Insert into #TenatsWidjetCount(TenantID,TenantName) 
      select ID,Name from Tenants


      Decalre @Dbname navarchar(100)
      Declare @Min Int;
      Declare @Max Int;
     set @Min=(Select min(TenantID ) from #TenatsWidjetCount )
     set @Max=(Select max(TenantID ) from #TenatsWidjetCount )




     while(@Min<=@Max)
     Begin
     print @min
     set @dbName=(Select DatabaseName From Tenant Where ID=@Min)

     Decalre @Dbname navarchar(100)





     Declare @Selectstring nvarchar(max);

     set @Selectstring='Update  #TenatsWidjetCount 
                  set Count=(select count(*) from   '+@DBname+'.dbo.Widjets)'

 print @Selectstring    
      execute sp_executesql @query=@Selectstring
      print @Selectstring 

      set @min=@min+1
     print @min
     end


     select * from #TenatsWidjetCount 

我们首先将数据加载到临时表中。使用temptable我运行循环,以便从租户表中列出的数据库列表中的每个widjet表中获取计数。

答案 2 :(得分:0)

如果您有一个随时间增长/缩小的租户列表,您将需要使用动态SQL。或者,您可以在添加或删除租户时使用动态SQL生成引用相关数据库的视图。

如果你想查看特定的数据库,但是你还不知道在哪里定位该数据库,那么你可以使用同义词来实现类似的结果,因为同义词目标在执行时绑定,而不是创建时间。