0

我将通过说我的 sql 不是很好来作为这个问题的序言 :)

我们试图通过拥有 2 个冗余表在 sql 中构建双缓冲实现。在任何时候,一张表处于活动状态,另一张处于非活动状态。这些表由我们在重新加载数据后切换的视图访问。当我们重新加载时,我们希望对非活动表执行操作,然后在完成时切换活动缓存。

我们有很多看起来有点像的代码:

IF @activeCache = 0
   BEGIN WORK ON TABLE 1 AS IT IS INACTIVE
ELSE
   BEGIN WORK ON TABLE 0 AS IT IS INACTIVE

问题是括号之间的代码不是微不足道的,所以我们最终复制了代码,唯一的区别是正在操作的表。我们认为表参数可能会有所帮助,但您无法插入其中(我们需要这样做)。我现在唯一的想法是使用 T4 模板为我们生成 crud,但我似乎无法让它们在数据库项目中工作。

有什么 sql 结构可以帮助我们吗?如果可能,我们宁愿不使用动态 sql。

4

3 回答 3

2

您可以使用CREATE SYNONYM有效地为对象创建永久别名(或“同义词”,如果您愿意的话)。您可以运行一次逻辑来决定要定位哪个表,然后运行:

CREATE SYNONYM WorkingTable FOR Table1
CREATE SYNONYM MainTable FOR Table2

然后切换:

DROP SYNONYM WorkingTable
DROP SYNONYM MainTable
CREATE SYNONYM WorkingTable FOR Table2
CREATE SYNONYM MainTable FOR Table1

在您的脚本中的其他任何地方,您都可以参考WorkingTable更新和MainTable阅读。

话虽如此,我同意其他关于这是否是最佳工作方式的评论/答案。

于 2013-02-28T13:29:00.270 回答
1

不要使用两个表并切换视图,而是使用一个主表和一个临时表。

当您准备好将数据迁移到主表时,您可以像这样在原子事务中执行此操作。

begin try
 begin tran
 delete * from MainTable with (tablockx)
 insert MainTable
 select * from StagingTable with (tablockx)
 commit

end try
begin catch
 rollback
 raiserror('An error occurred swapping staging data', 16,16)
end catch

这样一来,您始终在临时表上工作,因此识别要使用的正确表没有困难。

根据数据,您可能希望对主表进行增量更新:

-- delete rows which no longer exist
delete MainTable 
from MainTable
where not exists (select 1 from StagingTable where StagingTable.primaryKey = MainTable.primaryKey)

-- Insert new rows
insert MainTable 
select * 
from StagingTable
where not exists (select 1 from MainTable where StagingTable.primaryKey = MainTable.primaryKey)


-- update rows which have changed
update MainTable 
set  
   col1 = stagingTable.col1,
   col2 = stagingTable.col2
from MainTable inner join StagingTable on  StagingTable.primaryKey = MainTable.primaryKey
where 1=2
   -- Need to compare every column, only update if one is different
   -- Both null counts as the same - compare nullity 
   OR case when MainTable.col1 is null then 0 else 1 end <> case when StagingTable.col1 is null then 0 else 1 end
   OR MainTable.col1 <> StagingTable.col1
   OR case when MainTable.col2 is null then 0 else 1 end <> case when StagingTable.col2 is null then 0 else 1 end
   OR MainTable.col2 <> StagingTable.col2
于 2013-02-28T12:44:57.483 回答
1

您可以创建以@activeCache 作为参数的内联表值函数。根据该函数中的参数从适当的表中选择所有数据。TI 不确定性能。

于 2013-02-28T13:07:26.593 回答