2

我正在尝试将sys.columns中的记录加入到视图中,加入到它所引用的表的sys.columns中的记录中,因为我需要在视图中选择的列的is_nullableis_computeddefault_object_id列的值。

视图的sys.columns记录具有“不正确”的值,您可以通过运行以下示例查询来观察:

CREATE TABLE TestTable (
    FieldA int NOT NULL,
    FieldB int DEFAULT (1),
    FieldC as CONVERT(INT, FieldA + FieldB),
    FieldD int NOT NULL
)
GO

CREATE VIEW TestView WITH SCHEMABINDING AS
SELECT  FieldA, FieldC as TestC, FieldB + FieldC as TestD
FROM dbo.TestTable WHERE FieldD = 1
GO

SELECT  OBJECT_NAME(c.object_id) as ViewName, c.name as ColumnName,
        c.is_nullable as Nullable, c.is_computed as Computed,
   cast(CASE WHEN c.default_object_id > 0 THEN 1 ELSE 0 END as bit) as HasDefault
FROM sys.columns c
WHERE object_id = OBJECT_ID('TestTable')
GO

SELECT  OBJECT_NAME(c.object_id) as ViewName, c.name as ColumnName,
        c.is_nullable as Nullable, c.is_computed as Computed,
   cast(CASE WHEN c.default_object_id > 0 THEN 1 ELSE 0 END as bit) as HasDefault
FROM sys.columns c
WHERE object_id = OBJECT_ID('TestView')
GO

我曾尝试使用系统视图来加入依赖项,但它们没有为我们提供有关视图中的哪一列引用表中的哪一列的信息:

-- dm_sql_referenced_entities gives us all columns referenced, but all records
-- have referencing_minor_id 0, so we do not know which column refers to what
SELECT * FROM sys.dm_sql_referenced_entities('dbo.TestView', 'OBJECT')
GO

-- sql_dependencies gives us all columns referenced, but all records has
-- column_id 0 so we can not use this either of joining the columns
SELECT * FROM sys.sql_dependencies WHERE object_id = OBJECT_ID('TestView')
GO

-- sql_expression_dependencies just tells us what table we are referencing 
-- if view is not created WITH SCHEMABINDING. If it is, it will return columns,
-- but with referencing_minor_id 0 for all records, so not able use this either
SELECT * FROM sys.sql_expression_dependencies
    WHERE referencing_id = OBJECT_ID('TestView')
GO

某人提交的关于social.msdn 的未答复帖子似乎是同一问题: http ://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/4ae5869f-bf64-4eef-a952-9ac40c932cd4

4

3 回答 3

1

您说“我需要知道 TestView TestC 指的是计算列”。SQL Server 2008 R2 不支持此功能(虽然不确定 2012,但我对此表示怀疑)。

首先,您可以查询 sys.columns 或 INFORMATION_SCHEMA.COLUMNS 并且找不到您想要的。

如果你深入挖掘,你很可能会尝试 sys.sql_expression_dependencies 和 sys.dm_sql_referenced_entities (N'dbo.TestView', N'OBJECT'),但是你可以在那里找到表-列映射,而不是列-列。SQL 服务器通过“高级”对象(表、触发器...)而不是其详细信息(列)存储依赖关系信息。您会在 sys.sysdepends 中找到相同的内容。事实上,依赖信息在 SQL Server 中是不可靠的。

最后,您唯一的可能就是自己解析视图主体。它可以在 sys.sql_modules 中找到:

SELECT m.definition
FROM 
    sys.objects o
    JOIN sys.sql_modules m 
        ON m.object_id = o.object_id
WHERE 
    o.object_id = object_id('dbo.TestView')
    and o.type = 'V'

解析 T-SQL非常困难,它真的可以把你推到你努力的极限。例如,从视图中获取表引用应该或多或少容易,然后是表列,特别是如果您的视图是模式绑定的。但如果不是,那么……想想引用 OUTER APPLY 的星号,它引用递归 CTE……

无论如何,祝你好运!

于 2012-10-30T09:26:38.237 回答
1

目前,当创建视图时,有两个高级操作发生 - 解析和绑定。解析基本上是检查语句、关键字等的语法。绑定是将语句中的标识符(对象名、列名)映射到相应的对象(表、视图、函数、列等)和类型派生的过程。此外,在类似于 SELECT 语句的视图的情况下,您可以选择在 SELECT 列表中或在视图名称之后使用列引用和表达式的别名(例如:create view v1(a) as select i from t)。

绑定后,我们只保留元数据中的列别名和派生类型,因为视图在逻辑上是从查询表达式派生的表。因此,目前无法确定列别名映射到的表达式或其包含的内容(列或函数或文字等)。获取您要查找的信息的唯一方法是解析视图定义并执行您自己的绑定. 我相信我们已经有一个错误可以跟踪功能请求,以公开更丰富的依赖关系信息,这些信息涉及别名到视图定义中的列表达式的映射。

最后,SQL Server Developer Studio 或 Visual Studio 数据库项目使用托管 T-SQL 解析器来跟踪此类引用,以便您可以使用项目进行重构或重命名。希望这有助于澄清问题/当前的实施。

于 2014-06-17T23:36:00.793 回答
-1

似乎误解是 object_id 是 sys.columns 中的主键的假设。它不是。sys.columns 中的 object_id 与 sys.objects 中的 object_id 相关。所以:

SELECT C.*
FROM sys.objects T
INNER JOIN sys.columns C
ON T.object_id = C.object_id
WHERE T.type in ('S','U') -- System Tables and User Tables
AND T.name = 'Address' -- Table Name
order by C.Column_ID

将返回 AdventureWorks 中“地址”表中的列。

于 2015-06-11T00:00:04.570 回答