SQL Server 2005 - 从多个数据库中选择&将结果编译为单个查询

时间:2009-09-25 18:18:35

标签: asp.net sql-server vb.net

好的,基本情况:由于一些混合启动,项目最终不是一个,而是三个独立的数据库,每个数据库包含整个项目数据的一部分。所有三个数据库是相同的,只是说,10%的项目运行到第一个,然后一个新的数据库是由于代码更新和15%的项目运行到新的,然后另一个代码更改需要另一个新数据库用于项目的其余部分。同样,所有三个数据库中的相关表都完全相同。

现在,假设我想要考虑所有这三个数据库 - 请记住,由于主键问题等原因,它们不能只编译成单个数据库 - 并运行一个查看所有数据库的查询其中三个,从每个中选择一组给定的数据,然后将这三个集合编译成一个结果,并将其返回到我正在处理的报告页面。

作为参考,在其端点处,数据输出到ASP.Net/VB.Net支持的页面,特别是Gridview对象。幸运的是,它不需要编辑,只是显示出来。

解决这个烂摊子的最佳方法是什么?我认为创建一个临时表是我最好的选择,但说实话,我正在进入我不熟悉的SQL的一部分,并且会感谢有经验的人提供的任何指导。

5 个答案:

答案 0 :(得分:5)

我认为最好的办法就是把它吸收并合并数据库,即使将主键组合在一起也是一件很麻烦的事情。现在可能是一个很大的痛苦,但在整个项目的生命周期中,这将是10倍的痛苦。

您可以像Scott指出的那样在多个数据库之间建立联合,但随着应用程序变得更加复杂,您将陷入困境。例如,即使您通过为同一实体提供多个表/数据库来规避技术限制,但在PK中为逻辑实体设置重复项也是一个麻烦的世界。

如果必须,请实施变通方法解决方案,但我保证您以后会讨厌自己。

答案 1 :(得分:3)

为什么不在表格上使用3部分命名并将它们组合在一起?

select db1.dbo.Table1.Field1, 
       db1.dbo.Table1.Field2
from   db1.dbo.Table1
UNION 
select db2.dbo.Table1.Field1, 
       db2.dbo.Table1.Field2
from   db2.dbo.Table1
UNION 
select db3.dbo.Table1.Field1, 
       db3.dbo.Table1.Field2
from   db3.dbo.Table1
-- where  ...
-- order by ...

答案 2 :(得分:1)

您实际上可以在不同的数据库上连接表。如果我没记错,语法从“tablename.columnName”更改为“Server.Owner.tablename.columnName”。您需要以管理员身份运行某些存储过程以允许此连接。它也很慢但是让它工作的努力很低。

如果您有时间这样做,请查看数据仓库概念。这基本上是一个临时表,用于收集您需要报告的数据。

答案 3 :(得分:1)

您应该为每个感兴趣的表创建所谓的Partitioned View。这些视图执行底层基表的并集,最终添加一个syntetic列以使行唯一:

  CREATE VIEW vTableXDB 
  AS
  SELECT 'DB1' as db_key, *
  FROM DB1.dbo.table
  UNION ALL
  SELECT 'DB2' as db_key, *
  FROM DB2.dbo.table
  UNION ALL
  SELECT 'DB3' as db_key, *
  FROM DB3.dbo.table;

您为每个表创建一个这样的视图,然后在这些视图上设计报表,而不是在基表上。您必须将db_key添加到您的加入条件中。查询optimizzer对分区视图有一定的了解,并且可能能够创建执行right thing的计划并避免跨越多个dbs的连接,但这不能保证。如果事情变得混乱并且优化器无法识别分区导致执行时间非常糟糕,您可能必须将db_key移动到表中并在基表上添加一些人工检查约束,以便优化器可以理解分区(请参阅我链接的文章了解详情)。

答案 4 :(得分:0)

以Scott Ivey上面的优秀例子为基础,

  1. 使用表名别名来简化代码
  2. 假设您的数据 在三个数据库之间是唯一的,请使用UNION ALL而不是UNION
  3. 代码:

    select
        d1t1.Field1, 
        d1t1.Field2
    from db1.dbo.Table1 AS d1t1
    UNION ALL
    select
        d2t1.Field1, 
        d2.Field2
    from db2.dbo.Table1 AS d2t1
    UNION ALL
    select
        d3t1.Field1, 
        d3t1.Field2
    from db3.dbo.Table1 AS d3t1
    -- where  ...
    -- order by ...