13

为什么我必须编写“刷新视图”脚本,并在每次向视图添加或编辑某些字段时执行它们?

SQL Server 知道它需要在 Management Studio 中花哨的视图编辑窗口中编辑视图时刷新视图,那么为什么它不能在通过脚本编辑视图后告诉它的视图自行刷新呢?

4

3 回答 3

12

如果基础表发生变化,则需要刷新视图。这可以更改视图列的数据类型或重新排列其索引。因此,它需要知道。否则,你会针对它运行一个查询,它会很快爆炸。

您不必sp_refreshview为更改视图而奔跑。仅用于更改其基础表。

另外,请不要嘲讽开心球。

编辑:刚刚(连续)运行此代码以尝试重现您的问题。不幸的是,我无法按预期工作(SQL Server 2008):

create view MyView
as
select ProductKey, ProductID, ProductName, Price
from dbo.Products

select v.* from MyView v

alter view MyView
as
select ProductKey, ProductID, ProductName, Price*100 as MyPrice
from dbo. Products

select v.* from MyView v
于 2009-08-13T15:51:03.717 回答
4

在视图定义中使用WITH SCHEMABINDING以消除任何刷新的需要

并结合 ALTER VIEW,而不是设计师

编辑,2012 年 7 月,来自上面的链接。我的大胆

架构绑定

将视图绑定到基础表的架构。指定 SCHEMABINDING 时,不能以会影响视图定义的方式修改一个或多个基表。必须首先修改或删除视图定义本身,以删除对要修改的表的依赖关系。使用 SCHEMABINDING 时,select_statement 必须包含引用的表、视图或用户定义函数的两部分名称 (schema.object)。所有引用的对象必须在同一个数据库中。

不能删除参与使用 SCHEMABINDING 子句创建的视图的视图或表,除非删除或更改该视图以使其不再具有模式绑定。否则,数据库引擎会引发错误。此外,当这些语句影响视图定义时,对参与具有模式绑定的视图的表执行ALTER TABLE 语句会失败。

于 2009-08-13T15:52:27.613 回答
1

我在更改表时遇到了同样的问题。真正的解决方案是更改表的 DDL 触发器:

Create Trigger RefreshViewTrigger On Database FOr Alter_Table As
Declare @tname as nvarchar(256), @sql nvarchar(400);
Select @tname = EVENTDATA().value('(/EVENT_INSTANCE/SchemaName)[1]','nvarchar(100)')  + '.' +  EVENTDATA().value('(/EVENT_INSTANCE/ObjectName)[1]','nvarchar(100)');
Declare k cursor For Select distinct 'sp_refreshview ''' + o.name + '''' sql
    From sys.objects o Join sys.sql_expression_dependencies s On o.object_id = s.referencing_id   
    Where o.type = 'V' AND s.referenced_id = Object_id(@tname);  
Open k
Fetch Next from k into @sql
While @@FETCH_STATUS = 0
Begin
    Print( @sql )
    EXEC( @sql )
    Fetch Next from k into @sql
End
Close k
Deallocate k
Go

我在 2008 R2 上工作,甚至可能是更早的版本。

于 2021-05-19T08:32:02.863 回答