首页 > 解决方案 > 在 SQL Server 视图中查找计算列

问题描述

一位同事要求我帮助他们识别数据库中具有一个或多个计算列的视图。该数据库有数百个视图,因此他们正试图找到一种自动化的方式来完成这项任务。我没有在数据库中看到我期望的结果。这是一个例子:

--DROP TABLE dbo.Products

CREATE TABLE dbo.Products   
(  
    ProductID int IDENTITY (1,1) NOT NULL  
  , QtyAvailable smallint  
  , UnitPrice money   
);  

--DROP VIEW dbo.uvw_Products
CREATE VIEW dbo.uvw_Products
AS
    SELECT    ProductID
            , QtyAvailable
            , UnitPrice
            , (QtyAvailable * UnitPrice) AS InventoryValue
    FROM      dbo.Products;

-- Look at the view and find the computed column
SELECT OBJECT_SCHEMA_NAME(T.[object_id],DB_ID()) AS [Schema],   
        T.[name] AS [table_name], AC.[name] AS [column_name],   
        TY.[name] AS system_data_type, AC.[max_length],  
        AC.[precision], AC.[scale], AC.[is_nullable], AC.[is_ansi_padded], AC.[is_computed]
FROM sys.[views] AS T   
  INNER JOIN sys.[all_columns] AC ON T.[object_id] = AC.[object_id]  
 INNER JOIN sys.[types] TY ON AC.[system_type_id] = TY.[system_type_id] AND AC.[user_type_id] = TY.[user_type_id]  
WHERE T.[is_ms_shipped] = 0
AND T.[name] = 'uvw_Products'
ORDER BY T.[name], AC.[column_id]


-- Pulls up no results - no entries in sys.computed_columns
SELECT TOP 10 * 
FROM sys.computed_columns C
INNER JOIN sys.views V ON C.[object_id] = V.[object_id]
WHERE V.[name] = 'uvw_Products'

从这个简单的示例可以看出,SQL Server 似乎没有将值存储在 is_computed 列中。

我错过了什么?我们如何在视图中找到计算列?

标签: sql-server

解决方案


我知道这并不理想,我认为这个问题不存在万无一失的解决方案,但是根据您的命名约定,您可以在列名上连接到表 sys 视图,以便查看哪些列存在和不存在在那里。

例如:

SELECT v.*
FROM 
(
    SELECT  [Schema]        = OBJECT_SCHEMA_NAME(t.[object_id], DB_ID())
          , [table_name]    = t.[name] 
          , [column_name]   = vc.[name]
    FROM sys.[views] t  
    JOIN sys.[all_columns] vc ON t.[object_id] = vc.[object_id]
) v
LEFT JOIN 
(
    SELECT  [Schema]        = OBJECT_SCHEMA_NAME(t.[object_id], DB_ID())
          , [table_name]    = t.[name] 
          , [column_name]   = vc.[name]
    FROM sys.[tables] t  
    JOIN sys.[all_columns] vc ON t.[object_id] = vc.[object_id]
) t
    ON t.[column_name] = v.[column_name]
WHERE t.[table_name] IS NULL

回报:

Schema | table_name    | column_name
----------------------------------------
dbo    | uvw_Products  | InventoryValue

如果您的视图在其名称中包含源表,例如“uvw_Products”,您也可以在连接中使用它以避免其他表中的列妨碍。

同样,它并不理想,但缩小搜索范围的相对简单的解决方案


推荐阅读