sql - SQL Server: 间歇性的对象名'dbo.computed_view1' 由于绑定错误,无法使用视图或者函数'dbo.view2'

  显示原文与译文双语对照的内容
0 0

我正在使用 SQL Server 2008 R2.

我有一个观点,我们把它叫做 view1. 这个视图很复杂而且很慢。 它不能被做成索引视图,因为它使用了左连接和各种其他的。 因此,我们创建了一个基本的存储过程:

  1. 获得独占锁定
  2. 从视图中选择 * 到 computed_view1_tmp ;( 慢速)
  3. 在上面的计算表上创建索引( 慢)
  4. 重命名computed_view1到 computed_view1_todelete,并对它的索引执行相同的操作( 假定为快速)
  5. 重命名computed_view1_tmp到 computed_view1,并对它的索引执行相同的操作( 假定为快速)
  6. 删除表 computed_view1_todelete ( 慢速)
  7. 释放锁定。

当我们知道正在更改web应用程序中的数据时,我们运行这个过程。 然后我们有其他视图,比如使用computed_view1来代替 view1.

偶尔,我们会得到:

无效对象 NAME'dbo.computed_view1'. 无法使用视图或者函数'dbo 。view2 binding因为绑定错误。

我假设这是因为我们正在尝试访问 dbo.computed_view1,因为它被重命名。 我假设这是一个非常短的时间,但我的日志中看到这个错误的频率会让我想起来。 我每天在一个网站上获得的错误数量很多,每天有十几个用户活动。

在开发过程中,这里过程需要大约五秒钟,给定视图中的数据量。 重命名是即时的。在生产中,它必须花费更长的时间,但我不明白为什么。 我曾经看到这个过程在 90秒内无法获得独占锁。

关于如何修复或者更好解决问题的任何想法?

编辑:关于我的锁定的额外说明- 也许我没有做正确的事情:


BEGIN TRANSACTION

DECLARE @result int
EXEC @result = sp_getapplock @Resource = 'lock_computed_view1', @LockMode = 'Exclusive', @LockTimeout = 90
IF @result NOT IN ( 0, 1 ) -- Only successful return codes
 BEGIN
 PRINT @result
 RAISERROR ( 'Lock failed to acquire...', 16, 1 )
 END 
 ELSE
 BEGIN
//rest of the magic 
 END

EXEC @result = sp_releaseapplock @Resource = 'lock_computed_view1' 
COMMIT TRANSACTION

时间: 原作者:

0 0

如果锁定和事务范围正确,我希望其他事务等待,而不会看到视图丢失。 这可能是我不知道的SQL Server 特性。

通常不需要动态DDL就可以完成。 以下是两种方法:

  1. TRUNCATE 计算计算表并插入它。 这需要一个独家的。 无需重命名。所有这些都是原子的并且支持回滚。
  2. 使用具有相同架构的staging表。 继续做吧到目前为止没有任何服务中断。 然后,使用生产表来 SWITCH PARTITION 表。 这是快速而原子的。 这不需要企业版。

通过这些方法,只要不重命名就可以解决这个问题。

原作者:
...