By: Aaron Bertrand | Updated: 2014-12-02 | Comments (6) | Related: More > Database Administration
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.InfernoLocks
).
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:
About the author
This author pledges the content of this article is based on professional experience and not AI generated.
View all my tips
Article Last Updated: 2014-12-02