TL;DR;
当您创建视图时,SQL-server 会将视图信息存储在三个单独的 sys 表中:sys.views、sys.columns 和 sys.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.views、sys.columns 和 sys.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' 也是一个选项,它将刷新视图详细信息。