我有一个ETL(Microsoft SQL Server 2014),它使用组织的标准化命名约定每月复制一个大型SQL Server数据库。
不幸的是,名称每月更改一次,因此如果我编写代码或针对SQL Server数据库制作仪表板,则必须更改进行查询的几种产品的名称。
我想知道是否可以制作一个指向另一个数据库的SQL Server数据库,这样我每个月都可以拥有一个不变的名称,并且不会浪费我在服务器上的内存。
例如,我现在有以下数据库副本:
ViewModel
我想创建一个名为Jan_2018
Feb_2018
Mar_2018
Apr_2018
etc.
的副本/版本,对它的任何查询都指向可用的最新月份。
答案 0 :(得分:2)
为此,您可以使用synonyms
同义词是具有以下目的的数据库对象:
为另一个数据库对象提供替代名称,称为 作为基础对象,可以存在于本地或远程服务器上。
提供一层保护客户端应用程序的抽象 从对基础对象的名称或位置所做的更改。
其背后的想法是要创建一个空数据库,其中将包含自定义数据库的每个用户对象的同义词[Apr_2018]。
因此,当[May_2018]交付的同义词需要重新创建以指向此新数据库时。
当然,(重新)创建同义词是自动化的
同义词不会消耗内存,与视图相反,如果修改了基础对象的架构,它们也不会破坏
答案 1 :(得分:0)
正如亚历山大所说,同义词是最好的选择。为了了解如何使这种事情自动化,请参见下文。您可以继续运行此命令以获取将要运行的语句的输出,只需在要执行任何操作时取消对所有exec sp_executesql @sql
的注释即可。
use [curr_month]
GO
SET NOCOUNT ON;
-- You could automate this even by creating a select off master.sys.databases
declare @database varchar(100) = 'AdventureWorks'
declare @table varchar(100)
declare @obj varchar(100)
declare @sql nvarchar(1000)
create table #names
(
ident int identity(1,1),
objname varchar(100)
)
declare @table_count int
declare @counter int
--------------------------------------
-- Get tables
--------------------------------------
truncate table #names
set @sql = 'select [name] from ' + @database + '.sys.tables where is_ms_shipped = 0 order by [name]'
INSERT INTO #names (objname)
exec sp_executesql @sql
set @table_count = (select coalesce(count(*),0) from #names)
set @counter = 1
WHILE (@table_count > 0 ANd @counter <= @table_count)
BEGIN
select @obj = objname
from #names
where ident = @counter
set @sql = 'CREATE SYNONYM [dbo].[' + @obj + '] FOR [' + @database + '].[dbo].[' + @obj + ']';
print @sql
--exec sp_executesql @sql
set @counter += 1
END
--------------------------------------
-- Get procedures
--------------------------------------
truncate table #names
set @sql = 'select [name] from ' + @database + '.sys.procedures where is_ms_shipped = 0 order by [name]'
INSERT INTO #names (objname)
exec sp_executesql @sql
set @table_count = (select coalesce(count(*),0) from #names)
set @counter = 1
WHILE (@table_count > 0 ANd @counter <= @table_count)
BEGIN
select @obj = objname
from #names
where ident = @counter
set @sql = 'CREATE SYNONYM [dbo].[' + @obj + '] FOR [' + @database + '].[dbo].[' + @obj + ']';
print @sql
--exec sp_executesql @sql
set @counter += 1
END
-- etc. if you have views, functions, etc...
drop table #names
答案 2 :(得分:0)
在正常情况下,我的反应是“将所有内容存储在一个数据库中并修复表结构”。但是,这似乎是某种归档过程,并且合适的数据库是合适的。
可以想到的是在数据库级别使用synonym。 las,那不存在。
所以,我的建议是建立一个流程。上传最近一个月后的每个月,请执行以下操作:
那应该足够了-或绰绰有余。
您可以使用动态SQL创建这些对象,这些SQL遍历新加载的数据库中的相应对象。