我的应用程序使用来自外部来源的大量数据。这些数据必须定期更新。
在更新时,我对每个具有外部数据的表使用以下方法。
创建新表,用数据填充,创建索引。
删除现有表并重命名新表。
BEGIN TRAN
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET XACT_ABORT ON;
EXEC ('drop table TableWithExternalData')
EXEC sp_rename 'new_TableWithExternalData', 'TableWithExternalData'
COMMIT
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
在此期间,在应用程序日志中,我可以看到如下错误:
无效的对象名称'dbo.TableWithExternalData'。
或
无效的对象名称'dbo.TableWithExternalData'。 由于绑定错误,无法使用视图或函数“dbo.vSomeView”。
如何更新外部数据而不出错?
更新
使用此方法的原因如下:
它是“官方”:SSDT在生成表格更改脚本时使用。 SSMS使用相同的方法,但没有设置事务隔离级别。
它的工作速度非常快,没有长寿锁。不幸的是,我没有关于数据源变化的信息,有些表格相当大。完全加入更改,或者只是截断&&插入速度较慢。
实施和支持简单。在极少数模式更改的情况下,我只需在新导入的表中添加一列,并在计划数据刷新后生成新列。
但它在使用数据库的应用程序中产生运行时错误,所以我需要一些其他的方法。
更新2
稍加修改的代码有效。 但问题仍然是:外部数据刷新的最佳解决方案是什么?
运行时错误的原因:等待object_id的其他事务,而不是对象名称;删除表后,不再有旧ID的对象。
解决方案:不要删除同一事务中的旧表,而是将其重命名。
更多信息:http://www.sqlnotes.info/2011/12/02/sp_rename-causes-lock-leaking/
BEGIN TRAN
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET XACT_ABORT ON;
EXEC sp_rename 'TableWithExternalData', 'old_TableWithExternalData'
EXEC sp_rename 'new_TableWithExternalData', 'TableWithExternalData'
COMMIT
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
EXEC ('drop table old_TableWithExternalData')