SQL Server中存储的视图的定义在哪里

时间:2018-02-16 17:41:11

标签: sql-server sql-server-2012

我可以创建一个这样的表:

CREATE TABLE Test
(
    ID INT
)

然后创建一个视图来引用此表:

CREATE VIEW vwTest
AS
SELECT * FROM Test

然后我可以从视图中选择

SELECT * FROM vwTest

,这将返回ID

的所有结果

然后我可以修改基础表:

ALTER TABLE Test
ADD SomethingElse NVARCHAR(10)

然后当我再次从视图中选择时,我仍然只能看到ID列。

这让我相信视图是在创建时编译的,这是正确的吗?我认为这对性能更好?

SQL Server如何存储此编译?它是否在一个系统数据库中的某处保留了所有编译对象的定义?

1 个答案:

答案 0 :(得分:3)

TL; DR;

创建视图时,SQL-server会将视图信息存储在三个单独的sys表格中:sys.viewssys.columnssys.sql_expression_dependencies

更改基础表设计时,视图不会自动更新。您可以使用三种方法之一来更新视图信息:

  • Drop/Create视图。
  • sp_refreshview 'ViewName'
  • sp_refreshsqlmodule 'ViewName'

查看Microsoft Documentation,您可以看到:

  

如果视图依赖于已删除的表或视图,则当有人尝试使用该视图时,数据库引擎会生成错误消息。如果创建了新表或视图,并且表结构未从先前的基表更改以替换已删除的表,则视图将再次变为可用。如果新表或视图结构发生更改,则必须删除并重新创建视图。

     

如果未使用SCHEMABINDING子句创建视图,则应在对视图下方影响视图定义的对象进行更改时运行sp_refreshview。否则,查询时视图可能会产生意外结果。

     

创建视图时,有关视图的信息存储在以下目录视图中:sys.views,sys.columns和sys.sql_expression_dependencies。 CREATE VIEW语句的文本存储在sys.sql_modules目录视图中。

现在回答你的问题:

  

SQL Server如何存储此编译?

它将它们存储在以下目录视图中:sys.viewssys.columnssys.sql_expression_dependencies

  

是否在其中一个系统数据库中保留了所有编译对象的定义?

是的,确实如此。这就是为什么除非您再次删除/创建视图或仅运行:sp_refreshview 'ViewName',否则您无法获得更新的表格设计。

说完之后,按照你的例子。我创建了表和视图。以下是目录视图中的信息:

select v.name,
       v.object_id,
       v.type_desc,
       col.name,
       col.column_id,
       sed.referenced_class_desc,
       sed.referenced_entity_name
FROM sys.views as v
inner join sys.columns as col
    on col.object_id = v.object_id
inner join sys.sql_expression_dependencies as sed
    on sed.referencing_id = v.object_id
where v.name = 'vwTest'

我们得到了下一个结果:

name      object_id   type_desc   name           column_id   referenced_class_desc   referenced_entity_name
--------- ----------- ----------- -------------- ----------- ----------------------- -----------------------
vwTest    581577110   VIEW        ID             1           OBJECT_OR_COLUMN        Test

然后,您可以使用sp_refreshview 'ViewName'刷新视图,执行后,上面的查询将返回:

name      object_id   type_desc   name           column_id   referenced_class_desc   referenced_entity_name
--------- ----------- ----------- -------------- ----------- ----------------------- -----------------------
vwTest    581577110   VIEW        ID             1           OBJECT_OR_COLUMN        Test
vwTest    581577110   VIEW        SomethingElse  2           OBJECT_OR_COLUMN        Test

正如@Gareth Lyons所提到的,sp_refreshsqlmodule 'ViewName'也是一个选项,它将刷新视图细节。