清除并填充SQL Server中的表

问题描述 投票:0回答:2

我有一个非常简单且常见的方案:我需要每天更新两个表。它们通常结合在一起,并且仅由用户读取(除了我的维护工作(这需要几分钟才能运行)之外,没有其他更新发生)。

我需要两个表中的数据版本保持同步-它们都需要随时具有相同的数据版本。另外,我想尽可能地限制停机时间和锁定,因为在更新过程中可以主动查询表中的数据。最好的方法是什么?

sql sql-server sql-server-2016
2个回答
1
投票

没有足够的信息来彻底回答这个问题,但是,我会尽力提供第一遍。我建议使用更多信息来更新您的答案。

[假设一个表是只读的,而另一个表不是只读的,则在一个事务中包装一个截断和插入可能是一个可行的解决方案。

begin tran
truncate table tableA;
insert into TableA select * from TableB;
commit;

另一个方法是从两个来源中获取主键值,对重要的列(差异很重要的列)进行哈希处理,如果特定键上的哈希值不匹配,则更新表。

select primary_key, hashbytes('md5', lower(concat(columna,columnb,columnc))) "hash"
from tableA
except
select primary_key, hashbytes('md5', lower(concat(columna,columnb,columnc))) "hash"
from tableB

[另一种选择是标识需要更改的记录(以多种方式,例如使用上面的哈希系统),删除相应的PK并将新记录插入到目标表,而不是完整的截断。

/* using example code above .... */
delete from tableA where exists (select 1 from TableB where pk = pk and hash <> hash);
insert into tableA select * from TableB where not exists (select 1 from tableA where pk = pk);

1
投票

您可以将数据加载到具有不同架构的相同名称的表中,并将其换出。在这里加载staging.Table1和staging.Table2,然后将它们与dbo中的版本交换。目标表必须为空:

begin transaction
  truncate table dbo.Table1;
  truncate table dbo.Table2;
  alter table staging.Table1 switch to dbo.Table1;
  alter table staging.Table2 switch to dbo.Table2;
commit transaction

我认为交换应该在它自己的事务中,因为它将获取模式锁。您总是可以多次重新加载登台表,并且只要加载成功就可以交换。如果加载表的过程花费一些时间,则模式锁将干扰查询系统表,例如,如果您打开SSMS并尝试列出对象。

© www.soinside.com 2019 - 2024. All rights reserved.