我已经在这方面工作了好几天,我找不到合适的解决方案,我希望有人可以提供帮助。
我们有几个结构相同的数据库服务器(SQL Server),由链接服务器连接。我们有一堆视图可以跨所有服务器联合数据:
CREATE VIEW Things_view AS
SELECT id, thing
FROM server1.database1.dbo.stuff
UNION ALL
SELECT id, thing
FROM server2.database2.dbo.stuff
UNION ALL
SELECT id, thing
FROM server3.database3.dbo.stuff
这有几个问题:
所以我希望动态地重写它。目标是:
最重要的是:
当然,我无法在视图或函数中执行动态SQL。我尝试将其重写为存储过程,然后使用OPENROWSET trick从视图中查询存储的proc。这不起作用,因为我必须使用数据库名称完全限定proc,这将需要更多动态SQL(因为数据库名称不同)。然后我想到在主数据库上使用同义词,但这违反了维护和源代码控制目标。
如果需要,我可以创建一个包含服务器名称和数据库名称以及包含标志的新表。事实上,这是理想的,因为它集中了每个环境的配置。
我对此感到非常困惑,现在我正在联系你,互联网,请求最后的请求帮助!
答案 0 :(得分:2)
一种可能的解决方案是创建一个调整视图的存储过程。例如(未测试):
create procedure dbo.RecreateView
as
declare @sql varchar(max)
select @sql = IsNull(@sql + 'union all ','') +
'select * from ' + name + '.dbo.YourView '
from sys.databases
where name like 'DbNamePrefix%'
set @sql = 'create view dbo.YourView as ' + @sql
exec (@sql)
然后,您可以在添加数据库后调用存储过程,甚至可以从计划任务调用存储过程。
答案 1 :(得分:0)
如果您使用的是最新的SQL服务器
,使用同义词将是一个不错的选择答案 2 :(得分:0)
如果您有一个跟踪服务器和数据库的表,您可以在该表的触发器中动态构建视图。
看看另一个问题的答案。它提出了同样的建议,并有一些示例代码来改变触发器中的视图定义。
Dynamic table design (common lookup table), need a nice query to get the values
它可能适合你。
答案 3 :(得分:0)
这听起来像是数据仓库的工作...... http://en.wikipedia.org/wiki/Data_warehouse您需要按照设定的时间表运行,因此数据不是实时的。这是唯一的缺点。
使用类似于下面的文件从每个server[n].database.tablename
加载数据。
--Here is how you would administer the script. One single script that you would only need to modify when you added/removed servers.
So you can easily add this to source control or whatever. You can also do all this, without linked servers, if you look at some ETL tools. like SSIS
insert into dataserver1.datawarehouse.tablename select *,'svr1,'db','tablename' from svr1.db.tablename
insert into dataserver1.datawarehouse.tablename select *,'svr2,'db','tablename' from svr1.db.tablename
insert into dataserver1.datawarehouse.tablename select *,'svr3,'db','tablename' from svr1.db.tablename
insert into dataserver1.datawarehouse.tablename select *,'svr4,'db','tablename' from svr1.db.tablename
insert into dataserver1.datawarehouse.tablename select *,'svr5,'db','tablename' from svr1.db.tablename
insert into dataserver1.datawarehouse.tablename select *,'svr6,'db','tablename' from svr1.db.tablename
insert into dataserver1.datawarehouse.tablename select *,'svr7,'db','tablename' from svr1.db.tablename
insert into dataserver1.datawarehouse.tablename select *,'svr8,'db','tablename' from svr1.db.tablename
因此您需要创建许多插入语句。每个服务器/ db / table组合一个。
insert into dataserver1.datawarehouse.tablename select *,'svr1,'db','tablename' from svr1.db.tablename
因此,当您将数据加载到此新数据库表中时,您只需将每个行附加原始servername / databasename / tablename SO ....您的数据如下所示
col1 col2 col3 srvnam dbname tbl
foo bar some MSSQL1 master mycooltable
foo bar some MSSQL2 other mycooltable
现在,你所要做的就是查询一个表,它会非常快,干净。
答案 4 :(得分:0)
这是我的建议。创建一个表来存储特定服务器上每个视图的配置。 然后编写动态sql以基于这些配置创建视图脚本。 然后在服务器上运行视图脚本。 如果要添加新服务器,请将其添加到配置表中,该配置表可能具有触发器以自动为正在更改的视图重新创建脚本。或者从表中重新创建脚本并运行它们是每个部署的标准部分。