【发布时间】:2013-02-07 09:35:35
【问题描述】:
我是 SQL Server 新手。我已经尝试在网上四处寻找一段时间,但无法回答我的问题。谁能告诉我 SQL Server 2008 数据库中存储的视图到底在哪里?
【问题讨论】:
标签: sql-server sql-server-2008-r2
我是 SQL Server 新手。我已经尝试在网上四处寻找一段时间,但无法回答我的问题。谁能告诉我 SQL Server 2008 数据库中存储的视图到底在哪里?
【问题讨论】:
标签: sql-server sql-server-2008-r2
对您的问题的迂腐回答是……只有 Microsoft 知道视图元数据的物理存储位置。在从 SQL 2000 迁移到 SQL 2005(2008 所基于)的过程中,MS 摆脱了对过去存储视图(dbo.sysviews 和 dbo.syscmets)的系统表的直接访问,并添加了一个抽象层(通过隐藏资源数据库),这意味着您只能通过目录视图访问有关视图的元数据。 INFORMATION_SCHEMA 是一组符合 ANSI 的目录视图。虽然对于它们在版本之间的相对可移植性有点用处,但通常可以从 sql 2008 目录视图中获得更多信息 - 在本例中为 sys.views 和 sys.sql_modules
请注意,可以使用 ENCRYPTION 选项集创建视图,该选项集对包含视图 SQL 定义的 sys.cmets 记录进行加密。但如果没有加密,那么 sp_helptext [MyView] 会让您快速查看定义。
根据下面的第一条评论进行编辑,将“sys.cmets”替换为“sys.sql_modules”
【讨论】:
sys.syscomments,而不是sys.comments。其次,sys.syscomments 是一个遗留视图。
注意:基于这篇文章
http://improve.dk/archive/2012/08/27/where-does-sql-server-store-the-source-for-stored-procedures.aspx,很可能视图的定义(也)存储在sys.sysobjvalues系统表中。
可以使用sys.sql_modules 系统视图 (link) 查询所有用户 T-SQL 模块(在 SQL Server 2008 中)的列表。在这里,您可以找到用户视图的定义(列definition):
SELECT QUOTENAME(s.name)+'.'+QUOTENAME(o.name) AS full_object_name,
m.*
FROM sys.sql_modules m
JOIN sys.objects o ON m.object_id=o.object_id
JOIN sys.schemas s ON o.schema_id=s.schema_id
WHERE o.type='V' -- only view objects
ORDER BY full_object_name
如果你运行EXEC sp_helptext 'sys.sql_modules'你会得到这个系统视图的源代码:
CREATE VIEW sys.sql_modules AS
SELECT object_id = o.id,
definition = object_definition(o.id),
uses_ansi_nulls = sysconv(bit, o.status & 0x40000), -- OBJMOD_ANSINULLS
uses_quoted_identifier = sysconv(bit, o.status & 0x80000), -- OBJMOD_QUOTEDIDENT
is_schema_bound = sysconv(bit, o.status & 0x20000), -- OBJMOD_SCHEMABOUND
uses_database_collation = sysconv(bit, o.status & 0x100000), -- OBJMOD_USESDBCOLL
is_recompiled = sysconv(bit, o.status & 0x400000), -- OBJMOD_NOCACHE
null_on_null_input = sysconv(bit, o.status & 0x200000), -- OBJMOD_NULLONNULL
execute_as_principal_id = x.indepid
FROM sys.sysschobjs o
LEFT JOIN sys.syssingleobjrefs x ON x.depid = o.id AND x.class = 22 AND x.depsubid = 0 -- SRC_OBJEXECASOWNER
WHERE o.pclass <> 100
AND ((o.type = 'TR' AND has_access('TR', o.id, o.pid, o.nsclass) = 1)
OR (type IN ('P','V','FN','IF','TF','RF','IS') AND has_access('CO', o.id) = 1)
OR (type IN ('R','D') AND o.pid = 0))
你可以看到这个视图查询了另一个系统对象sys.sysschobjs我认为是用来存储视图定义的系统表。
注意 1:使用INFORMATION_SCHEMA.VIEWS 查找视图的定义不是一种可靠的方法,因为INFORMATION_SCHEMA.VIEWS.VIEW_DEFINITION 列定义是convert(nvarchar(4000), object_definition(object_id))(最多4000 个字符)。
注意 2:您应该使用 sys.sql_modules.definition 列:definition = object_definition(o.id)。如果您查看object_definition 函数(link),您将看到返回类型为nvarchar(max)。
【讨论】:
如果您的意思是视图生成的表,那么答案是它们根本没有存储。视图只是一个查询,这就是它所存储的全部内容。当您查询视图时,数据库引擎只会获取视图查询的结果,然后查询这些结果。
数据库引擎可以存储“物化”视图,但这是一个不同的主题。
【讨论】:
在系统表中。
以下查询将检索它们...
选择 TABLE_NAME 作为 ViewName, VIEW_DEFINITION 作为 ViewDefinition FROM INFORMATION_SCHEMA.Views
要正常查看编辑它们,您可以查看工作室管理器中表格下的视图文件夹。
您可以使用设计器或编写脚本从此文件夹中创建/编辑它们。
【讨论】:
View 是一个简单的 SQL 语句,存储在数据库模式 (INFORMATION_SCHEMA.Views) 中。因此,当我们调用视图时,SQL 语句会被执行并从主物理表返回行。
您还可以将视图视为存储定义(sql 语句)但不存储结果的逻辑表。
您可以使用以下语句查看定义,如上面 Dan 所说,仅当视图定义未加密时: SELECT TABLE_NAME 作为 ViewName,VIEW_DEFINITION 作为 ViewDefinition FROM INFORMATION_SCHEMA.Views
更多详情请查看@MSDN。
【讨论】:
VIEW_DEFINITION 仅限于 4000 [n] 个字符。