复制SQL库

时间:2019-02-15 16:29:05

标签: sql sql-server

我有一个ETL(Microsoft SQL Server 2014),它使用组织的标准化命名约定每月复制一个大型SQL Server数据库。

不幸的是,名称每月更改一次,因此如果我编写代码或针对SQL Server数据库制作仪表板,则必须更改进行查询的几种产品的名称。

我想知道是否可以制作一个指向另一个数据库的SQL Server数据库,这样我每个月都可以拥有一个不变的名称,并且不会浪费我在服务器上的内存。

例如,我现在有以下数据库副本:

ViewModel

我想创建一个名为Jan_2018 Feb_2018 Mar_2018 Apr_2018 etc. 的副本/版本,对它的任何查询都指向可用的最新月份。

3 个答案:

答案 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遍历新加载的数据库中的相应对象。