2

I have some queries that run against Query Store, the view sys.query_store_wait_stats is not in SQL Server 2016, but it is in SQL Server 2017. I want my queries to work in SQL Server 2016 and SQL Server 2017+.

To accomplish this I used IF EXISTS as below

EXEC sp_query_store_flush_db;
SELECT * INTO Admin.dbo.query_store_runtime_stats FROM sys.query_store_runtime_stats;
SELECT * INTO Admin.dbo.query_store_runtime_stats_interval FROM sys.query_store_runtime_stats_interval;
SELECT * INTO Admin.dbo.query_store_plan FROM sys.query_store_plan;
SELECT * INTO Admin.dbo.query_store_query FROM sys.query_store_query;
SELECT * INTO Admin.dbo.query_store_query_text FROM sys.query_store_query_text;
IF EXISTS(select * FROM sys.views where name = 'query_store_wait_stats') -- View not in SQL Server 2016
 Begin
 SELECT * INTO Admin.dbo.query_store_wait_stats FROM sys.query_store_wait_stats; 
 End
SELECT * INTO Admin.dbo.query_context_settings FROM sys.query_context_settings;

Which would seem like a good solution, EXCEPT that, the below does not return any results on SQL Server 2017 database with Query Store active

select * FROM sys.views where name = 'sys.query_store_wait_stats'

Microsoft has this answer: How do I find all views in a database?

USE <database_name>; 
GO 
SELECT name AS view_name 
 ,SCHEMA_NAME(schema_id) AS schema_name 
 ,OBJECTPROPERTYEX(object_id,'IsIndexed') AS IsIndexed 
 ,OBJECTPROPERTYEX(object_id,'IsIndexable') AS IsIndexable 
 ,create_date 
 ,modify_date 
FROM sys.views; 

But it only returns user views, NOT system views.

A couple of simple tests also do not return the system view, which is present. You can try them without a WHERE and not get any system views.

select * FROM sys.views where name = 'sys.query_store_wait_stats'
SELECT *
 -- DISTINCT NAME 
FROM SYS.OBJECTS
WHERE TYPE IN ('U','V')
AND NAME= 'query_store_wait_stats'

sys.query_store_wait_stats

I could test for SQL Server version, but If the view gets added to SQL Server 2016 in a Service Pack, I want my query to have only checked for the presence of the view.

How do I find (or test for) the presence of a system view?

MDCCL
8,5303 gold badges32 silver badges63 bronze badges
asked Jul 16, 2019 at 15:09

3 Answers 3

3

You just need to remove the schema name and use all_views.

SQL Fiddle: http://www.sqlfiddle.com/#!18/9eecb/50897

select * from sys.all_views where name = 'query_store_wait_stats'
James Jenkins
6,3187 gold badges49 silver badges88 bronze badges
answered Jul 16, 2019 at 15:19
4

It's not just if objects exist as a whole, you also have to make sure columns line up. Microsoft adds new stuff, and sometimes backports it. It's nice not to rely on version checking, or worry about it failing if someone hasn't rebooted after patching.

As a related example, when dm_exec_query_stats got information about tempdb spills and I wanted to show those columns, I used code like this to test for them.

DECLARE @tempdb_spills BIT = 0;
IF 4 = ( SELECT COUNT(*)
 FROM sys.all_columns AS ac
 WHERE ac.name IN ( 'total_spills', 'last_spills', 'min_spills', 'max_spills' )
 AND OBJECT_NAME(ac.object_id) = 'dm_exec_query_stats' )
SET @tempdb_spills = 1;
answered Jul 16, 2019 at 17:11
1

You could use the system_views instead of all_views.

SELECT * FROM sys.system_views WHERE name = 'query_store_wait_stats'

That way you can avoid selecting user defined views at the same time.

answered Jul 16, 2019 at 15:26
1
  • Thank you this works as well. Commented Jul 16, 2019 at 15:40

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.