クエリストアに対して実行するクエリがいくつかあります。ビューsys.query_store_wait_stats
はSQL Server 2016にはありませんが、SQL Server 2017にあります。SQLServer 2016およびSQL Server 2017+でクエリを機能させたいです。
これを達成するために、以下のようにIF EXISTS
を使用しました
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;
これは良い解決策のように思われますが、それ以外は、クエリストアがアクティブなSQL Server 2017データベースで結果が返されません
select * FROM sys.views where name = 'sys.query_store_wait_stats'
Microsoftには この回答:データベース内のすべてのビューを見つける方法はありますか?
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;
ただし、システムビューではなく、ユーザービューのみが返されます。
いくつかの簡単なテストでも、存在するシステムビューは返されません。 WHERE
なしで試してみると、システムビューを取得できません。
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'
SQL Serverのバージョンをテストすることはできましたが、ビューがサービスパックのSQL Server 2016に追加された場合、クエリでビューの存在のみをチェックする必要があります。
システムビューの存在を見つける(またはテストする)にはどうすればよいですか?
スキーマ名を削除してall_views
を使用するだけです。
SQLフィドル: http://www.sqlfiddle.com/#!18/9eecb/50897
select * from sys.all_views where name = 'query_store_wait_stats'
オブジェクトが全体として存在するだけでなく、列が整列していることも確認する必要があります。マイクロソフトは新しいものを追加し、時にはそれをバックポートします。バージョンチェックに依存しないこと、またはパッチ適用後に誰かが再起動していない場合に失敗することを心配しないのはいいことです。
関連する例として、dm_exec_query_stats
tempdbの流出に関する情報を得て、それらの列を表示したかったので、このようなコードを使用してテストしました。
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;
All_viewsの代わりにsystem_viewsを使用できます。
SELECT * FROM sys.system_views WHERE name = 'query_store_wait_stats'
これにより、ユーザー定義ビューを同時に選択することを回避できます。