如何从DB中选择DB来自表

时间:2014-11-14 08:30:56

标签: sql-server tsql

我有一个包含3个数据库的.NET项目(CommonAkten_DEAkten_IT)。所有3个数据库都在同一个SQL Server上。在数据库Akten_DEAkten_IT中,我有一个表Akt,其中存储来自DE或IT的行为。但是在数据库Common中我有表AktComm,其中我存储了来自两个数据库的所有行为。在AktComm的表Common中,我还有一个列DB,其中存储了行为数据库名称。

Akt中的表Akten_DE

|ID        | ...
|AKT140122 | ... 
|AKT140131 | ...

Akt中的表Akten_IT

|ID        | ...
|AKT140127 | ... 
|AKT140162 | ...

AktComm中的表Common

|ID        |DB       |
----------------------
|AKT140122 |Akten_DE |
|AKT140127 |Akten_IT |
|AKT140131 |Akten_DE |
|AKT140162 |Akten_IT |
----------------------

问题是如何在Common数据库中编写选择,但是根据Akten_IT的值,从Akten_DECommon.dbo.AktComm.DB获取数据。

这样的事情:

SELECT akt.* 
FROM AktComm comAkt 
INNER JOIN "comAkt.DB".dbo.Akt akt ON comAkt.ID = akt.ID

有人能帮助我吗?

感谢。

3 个答案:

答案 0 :(得分:2)

我假设表Akt在每个数据库中都有相同的模式。

执行此操作的基本查询是跨数据库的简单连接,并将结果联合在一起:

SELECT co.ID, de.*
FROM AktComm co
JOIN AKTEN_DE.dbo.Akt de   
  ON co.ID = de.ID collate database_default
 AND co.DB = 'Akten_DE'
UNION ALL
SELECT co.ID, it.*
FROM AktComm co
JOIN AKTEN_DE.dbo.Akt it
  ON co.ID = it.ID collate database_default
 AND co.DB = 'Akten_IT'

当然,这不是很灵活,因为当您添加需要重构查询的新数据库时。如果添加了新的数据库,下面的动态sql将查询数据库。请注意,我不会在DB上进行过滤,因为这会引入SQL注入泄漏,如果AktComm表没有在DB字段上进行分区,那么在宏观方案中,性能差异将是微不足道的。 / p>

declare @sql nvarchar(max)

;WITH dbs as (select distinct DB from AktComm where db_id(DB) is not null)
select @sql = isnull(@sql + N' UNION ALL', N'') + N'
  SELECT co.ID, ' + QUOTENAME(DB) + N'.*
    FROM AktComm co
    JOIN ' + QUOTENAME(DB) + N'.dbo.Akt de   
      ON co.ID = de.ID collate database_default'
  from dbs
 print (@sql)
 exec (@sql)

答案 1 :(得分:1)

您无法轻松完成此操作 - 您必须与Common.AktComm.DB列进行比较,然后执行或其他SELECT语句:

DECLARE @DB VARCHAR(20)

SELECT @DB = AktComm.DB 
FROM Common
WHERE ID = akt.ID

IF (@DB = 'Akten_DE') THEN
   SELECT akt.* 
   FROM AktComm comAkt 
   INNER JOIN Akten_DE akt ON comAkt.ID = akt.ID
END

IF (@DB = 'Akten_IT') THEN
   SELECT akt.* 
   FROM AktComm comAkt 
   INNER JOIN Akten_IT akt ON comAkt.ID = akt.ID
END

你不能"参数化"带有参数值的数据库,表或列名称或数据库列中的值。

答案 2 :(得分:1)

对于您的示例,这将有效(尽管可能对您的需求来说太慢,具体取决于数据量等),但如果您的真实世界问题有两个或三个以上的数据库,则可能无法实现。

SELECT 
    COALESCE(AKTde.ID, aktIT.ID) AS ID
FROM 
    AktComm comAkt 
    LEFT JOIN AKTEN_DE.dbo.Akt aktDE 
        ON comAkt.ID = aktDE.ID
        AND comAkt.DB = 'Akten_DE'
    LEFT JOIN AKTEN_IT.dbo.Akt aktIT 
        ON comAkt.ID = aktIT.ID
        AND comAkt.DB = 'Akten_IT'