Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find computed columns in SQL Server views

Tags:

sql-server

A colleague asked me to help them to identify the views in a database that have one or more computed columns. The database has hundreds of views so they're trying to find an automated way to accomplish this task. I am not seeing the results in the database that I was expecting. Here is an example:

--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'

As you can see from this simple example, SQL Server does not seem to be storing the value in the is_computed column.

What am I missing? How can we find the computed columns in views?

like image 953
Michael Avatar asked Nov 07 '22 06:11

Michael


1 Answers

I know it's not ideal, I don't think a fool-proof solution exists for this problem, but depending on your naming conventions you could do a join to the tables sys view on column names so see which columns exist and don't exist in there.

for example:

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

Returns:

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

And if your views contain the source table in its name like 'uvw_Products' you could also use that in your join to avoid columns in other tables getting in the way.

Again its not ideal but a relatively simple solution to narrow the search

like image 66
Osie J O'Connor Avatar answered Dec 01 '22 00:12

Osie J O'Connor