我将通过说我的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。
答案 0 :(得分: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
进行读取。
话虽如此,我同意其他评论/答案,质疑这是否是最好的工作方式。
答案 1 :(得分: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
答案 2 :(得分:1)
您可以创建内联表值函数,该函数将@activeCache作为参数。根据该函数中的参数从正确的表中选择所有数据。 TI对性能不确定。