Problem
In my last tip, I demonstrated SQL Server metadata queries to help you find all the tables in your SQL Server database that meet some criteria. You might also be interested in similar queries to discover SQL Server views that have certain properties or use certain syntax.
Solution
Again, I have many SQL Server scripts lying around that I use quite often for exactly this purpose – sometimes I want to know which SQL Server views in a database are indexed, and sometimes I want to know how many of my views are dependent upon other views.
And again these are mostly just discovery scripts, meant only to list the views that meet the given criteria – you will need to dig further to get more details about the objects and, more importantly, to fix any that you deem to be problems.
All SQL Server views with SCHEMABINDING
SELECT [view] = s.name + N'.' + v.name
FROM sys.views AS v
INNER JOIN sys.schemas AS s
ON v.[schema_id] = s.[schema_id]
WHERE EXISTS
(
SELECT 1 FROM sys.sql_modules AS m
WHERE m.[object_id] = v.[object_id]
AND m.is_schema_bound = 1
);All SQL Server views that are indexed
SELECT [view] = s.name + N'.' + v.name
FROM sys.views AS v
INNER JOIN sys.schemas AS s
ON v.[schema_id] = s.[schema_id]
WHERE EXISTS
(
SELECT 1 FROM sys.indexes AS i
WHERE i.[object_id] = v.[object_id]
AND i.index_id = 1
);All SQL Server views that use SELECT *
SELECT [view] = s.name + N'.' + v.name
FROM sys.views AS v
INNER JOIN sys.schemas AS s
ON v.[schema_id] = s.[schema_id]
WHERE EXISTS
(
SELECT 1 FROM sys.views AS sv
INNER JOIN sys.schemas AS ss
ON sv.[schema_id] = ss.[schema_id]
CROSS APPLY sys.dm_sql_referenced_entities
(ss.name + N'.' + sv.name, N'OBJECT') AS r
WHERE sv.[object_id] = v.[object_id]
AND r.referenced_minor_id = 0
AND r.is_select_all = 1
);All SQL Server views that reference other views
SELECT [view] = s.name + N'.' + v.name
FROM sys.views AS v
INNER JOIN sys.schemas AS s
ON v.[schema_id] = s.[schema_id]
WHERE EXISTS
(
SELECT 1 FROM sys.views AS sv
INNER JOIN sys.schemas AS ss
ON sv.[schema_id] = ss.[schema_id]
CROSS APPLY sys.dm_sql_referenced_entities
(ss.name + N'.' + sv.name, N'OBJECT') AS r
INNER JOIN sys.views AS rv
ON r.referenced_id = rv.[object_id]
WHERE sv.[object_id] = v.[object_id]
);All SQL Server views that are referenced by other views
SELECT [view] = s.name + N'.' + v.name
FROM sys.views AS v
INNER JOIN sys.schemas AS s
ON v.[schema_id] = s.[schema_id]
WHERE EXISTS
(
SELECT 1 FROM sys.views AS sv
INNER JOIN sys.schemas AS ss
ON sv.[schema_id] = ss.[schema_id]
CROSS APPLY sys.dm_sql_referencing_entities
(ss.name + N'.' + sv.name, N'OBJECT') AS r
INNER JOIN sys.views AS rv
ON r.referencing_id = rv.[object_id]
WHERE sv.[object_id] = v.[object_id]
);All SQL Server views with NOLOCK or READUNCOMMITTED hints
Note that any query that relies on brute force parsing of the object’s definition (since the metadata does not explicitly note things like table hint usage) is potentially subject to false positives. This will return all views using either of these table hints, but could returns views with the hints commented out, or with those words being used as part or all of an alias or other entity name (consider a table named dbo.Infer<b>noLock</b>s).
SELECT [view] = s.name + N'.' + v.name
FROM sys.views AS v
INNER JOIN sys.schemas AS s
ON v.[schema_id] = s.[schema_id]
WHERE EXISTS
(
SELECT 1 FROM sys.sql_modules AS m
WHERE m.[object_id] = v.[object_id]
AND (LOWER(m.[definition]) LIKE N'%nolock%'
OR LOWER(m.[definition]) LIKE N'%readuncommitted%')
);All SQL Server views that use TOP (100) PERCENT
TOP (100) PERCENT in a view is meaningless, and is usually used merely to support an ORDER BY clause – which is also meaningless in a view. If you use this construct, it will get optimized away and not obeyed anyway, so why give the impression that a SELECT from the view without an ORDER BY might guarantee that the results will be returned in that order, when that guarantee can’t possibly be made? I also add a check for TOP 99.99 PERCENT and TOP 2147483647, since these are common “workarounds.”
Note that this is another one that relies on parsing the entire definition of the view, and therefore, it could produce false positives.
SELECT [view] = s.name + N'.' + v.name
FROM sys.views AS v
INNER JOIN sys.schemas AS s
ON v.[schema_id] = s.[schema_id]
WHERE EXISTS
(
SELECT 1 FROM sys.sql_modules AS m
WHERE m.[object_id] = v.[object_id]
AND (LOWER(m.[definition]) LIKE N'%top%100%percent%'
OR LOWER(m.[definition]) LIKE N'%top%99.99%percent%'
OR LOWER(m.[definition]) LIKE N'%top%2147483647%')
);Conclusion
I hope that has provided a good variety of metadata queries to help you identify views that meet some criteria. I certainly didn’t cover every potential scenario, but tried to touch enough areas to give you a head start on any areas I didn’t hit directly.
Next Steps
- Bookmark this page, in case you need quick access to these code samples in the future.
- Review the following tips and other resources:

Aaron Bertrand (@AaronBertrand) is a passionate technologist with industry experience dating back to Classic ASP and SQL Server 6.5. He also blogs at sqlblog.org.
- MSSQLTips Awards: Author of the Year – 2016, 2023 | Leadership (200+ tips) – 2022


