TSQL动态数据库引用

时间:2017-05-25 15:27:01

标签: sql-server tsql

4个数据库,全部在同一个实例中,具有相同的表结构。

我在“common”数据库中有一个复杂的视图,它不引用特定的数据库并使用DB_NAME()

我试图从其他数据库中运行一个新视图,只是在公共数据库中从该视图执行SELECT *,该公共数据库引用其自己的数据库中的数据。

我的问题是其他数据库的视图将公共数据库保持为当前DB_NAME()

有解决方法吗?

我的目标是只保留一个TSQL代码副本,我可以从一个公共位置的所有数据库运行,然后访问特定于其运行的数据库的数据,并将“common”db中的视图作为模板。

2 个答案:

答案 0 :(得分:1)

如果你可以使用存储过程而不是视图,那么这样的东西可以工作。

create procedure dbswitcher
@whatDB as varchar(5)
as
begin

    /*
        EXECUTION EXAMPLE
        exec dbswitcher 'DB3'
    */
    if @whatDB = 'DB1'
        begin
            select * from DB1..TableA
        end
    if @whatDB = 'DB2'
        begin
            select * from DB2..TableA
        end
    if @whatDB = 'DB3'
        begin
            select * from DB3..TableA
        end
    if @whatDB = 'DB4'
        begin
            select * from DB4..TableA
        end
end

答案 1 :(得分:0)

如果您希望查看在同一服务器上并行共享的作用域公用表,则可以执行三部分命名(db)。(schema)。(TableName)并执行联合。或者你可以做sp_MSforeachdb的黑色艺术。

假设我在数据库Tester和Tester2上分别有两个具有相同结构的表。它们只是具有PersonId,FirstName,LastName和CountryID的表。所有我真正想要看到的是跨越dbs的人,但我希望得到我从中得到它的dbname()的引用。

USE master
GO

Select
  'Tester' AS Environment
,  FirstName
,  LastName
from Tester.dbo.tePerson
union
Select 
  'Tester2'
, FirstName
, LastName
from Tester2.dbo.tePerson

--As far as I know MS warns against the all powerfull sp_MSforeachdb so you use this with knowing that some day MS may blow it up.
DECLARE @Storage table ( DbName varchar(64), FirstName VARCHAR(128), LastName VARCHAR(128))

INSERT INTO @Storage
--Essentially this code says use tokenized database[?] only for names I specify like Tester and on this table run this recursive over the table I tell you.
EXECUTE master.sys.sp_MSforeachdb 'USE [?];  if db_name() like ''%Tester%'' Select db_name(), FirstName, LastName From dbo.tePerson'

Select *
From @Storage