将 UNION 视图重写为动态视图
我已经为此工作了几天,但找不到合适的解决方案,希望有人能提供帮助。
我们有几个结构相同的数据库服务器(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
这有几个问题:
- 当我们添加服务器时,我们必须修改 意见。
- 我们的开发环境需要 相同数量的数据库和假链接 服务器,以便我们可以安装这些 意见。
- 有些服务器没有 包括来自其他一些服务器的数据。今天,我们通过这些服务器上的自定义视图来做到这一点,但这是一个部署噩梦。
所以我希望动态地重写它。目标是:
- 允许开发环境 包含不同数量的数据库。他们很可能 一台服务器上有 2 个或更多数据库。
- 为每个服务器提供一种方法 指定哪些其他服务器 包括在结果中。
- 最小化复杂性,以便 解决方案仍然有些 可维护。
- 创建一种解决方案 源代码受控并用于所有 服务器。
最重要的是:
- 将其公开为具有相同内容的视图 名称,这样我们就不必重写我们的 整个应用程序。
当然,我不能在视图或函数中执行动态 SQL。我尝试将其重写为存储过程,然后使用 OPENROWSET技巧从视图查询存储过程。这不起作用,因为我必须使用数据库名称完全限定过程,这将需要更多动态 SQL(因为数据库名称不同)。然后我考虑在主数据库上使用同义词,但这违反了维护和源代码控制目标。
我完全可以创建一个包含服务器名称和数据库名称以及包含标志(如果需要)的新表。事实上,这是理想的,因为它集中了每个环境的配置。
我对此完全困惑不解,现在我向互联网求助,请求帮助!
I've been working on this for days and I can't find a proper solution, I'm hoping someone can help.
We have several database servers (SQL Server) with identical structures, connected by linked servers. We have a bunch of views that union data across all the servers:
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
There are several problems with this:
- When we add servers, we have to modify
views. - Our development environments need
the same number of databases and fake linked
servers so we can install these
views. - Some of the servers do not
include data from some of the other servers. Today we do this with customized views on those servers but that's a deployment nightmare.
So I was hoping to rewrite this dynamically. The goals are:
- Allow development environments to
contain a different number of databases. They are likely to
have 2 or more databases on a single server. - Provide a way for each server to
specify which other servers to
include in the results. - Minimize the complexity so the
solution remains somewhat
maintainable. - Create one solution that can be
source controlled and used on all
servers.
And most importantly:
- Expose it as a view with the same
name so we don't have to rewrite our
entire application.
Of course, I can't do dynamic SQL in a view or function. I tried rewriting this as a stored procedure, then using the OPENROWSET trick to query the stored proc from a view. That didn't work because I had to fully qualify the proc with the database name, which would require more dynamic SQL (because the database names are different). Then I thought about fooling around with synonyms on the master database but that violates the maintenance and source control goals.
I'm perfectly OK with creating a new table with server names and database names and inclusion flags if needed. In fact, that is ideal because it centralizes the configuration for each environment.
I've been completely baffled by this and now I'm reaching out to you, Internet, in a last-ditch plea for help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
一种可能的解决方案是创建一个调整视图的存储过程。例如(未经测试):
您可以在添加数据库后调用存储过程,甚至可以从计划任务中调用存储过程。
One possible solution is to create a stored procedure that adjusts the view. For example (not tested):
You could then call the stored procedure after you add a database, or even from a scheduled task.
如果您使用最新的 SQL Server,使用 Synonym 将是一个不错的选择
Using Synonym would be a good option if you are using latest SQL server
如果您有一个跟踪服务器和数据库的表,您可以在该表的触发器中动态构建视图。
看看这个对另一个问题的回答。它建议同样的事情,并有一些示例代码来更改触发器中的视图定义。
动态表设计(通用查找表),需要一个很好的查询来获取值
它可能适合你。
If you have a table keeping track of servers and databases you could build the view dynamically in a trigger on that table.
Look at this answer to another question. It suggests the same thing and has some sample code to alter a view definition in a trigger.
Dynamic table design (common lookup table), need a nice query to get the values
It might work for you.
这是我的建议。创建一个表来存储特定服务器上每个视图的配置。
然后根据这些配置编写动态sql来创建视图脚本。
然后在服务器上运行查看脚本。
当您想要添加新服务器时,请将其添加到配置表中,该配置表可以有一个触发器来自动为正在更改的视图重新创建脚本。或者从表中重新创建脚本并运行它们成为每个部署的标准部分。
Here is what I'd suggest. Create a table to store the configuration for each view on the particular server.
Then write dynamic sql to create the view script based on those configurations.
Then run the view script on the server.
When you want to add a new server, add it to the configurationtable which could have a trigger to automatically recreate the scripts for the views that are being changed. Or have recreating scripts from the table and running them be a standard part of every deployment.
这听起来像是数据仓库的工作... http://en.wikipedia.org/wiki/Data_warehouse 您需要它按设定的时间表运行,这样数据就不是实时的。这是唯一的缺点。
使用类似于下面的文件从每个
server[n].database.tablename
加载数据。所以你需要创建许多插入语句。您拥有的每个服务器/数据库/表组合都有一个。
insert into dataserver1.datawarehouse.tablename select *,'svr1,'db','tablename' from svr1.db.tablename
因此,当您将数据加载到这个新的数据库表中时,您只需附加到每一行原始服务器名/数据库名/表名所以......你的数据看起来像这样
现在,你所要做的就是查询一个表,它会非常快,而且干净。
This sounds like a job for a data warehouse... http://en.wikipedia.org/wiki/Data_warehouse You would need this to run at a set schedule so the data would not be realtime. That is the only downside.
Load data from each
server[n].database.tablename
using a file similar to the one below.So you are required to create many insert statements. One for each server/db/table combo you have.
insert into dataserver1.datawarehouse.tablename select *,'svr1,'db','tablename' from svr1.db.tablename
So as you load the data into this new database table, you will simply append to every row the original servername/databasename/tablename SO.... Your data looks like this
Now, all you have to do is query off of one table, it will be really fast, and clean.