web-dev-qa-db-ja.com

SQL Serverデータベースのシステムビューを照会するにはどうすればよいですか?

クエリストアに対して実行するクエリがいくつかあります。ビュー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'

sys.query_store_wait_stats

SQL Serverのバージョンをテストすることはできましたが、ビューがサービスパックのSQL Server 2016に追加された場合、クエリでビューの存在のみをチェックする必要があります。

システムビューの存在を見つける(またはテストする)にはどうすればよいですか?

2
James Jenkins

スキーマ名を削除してall_viewsを使用するだけです。

SQLフィドル: http://www.sqlfiddle.com/#!18/9eecb/50897

select * from sys.all_views where name = 'query_store_wait_stats'
3
LowlyDBA

オブジェクトが全体として存在するだけでなく、列が整列していることも確認する必要があります。マイクロソフトは新しいものを追加し、時にはそれをバックポートします。バージョンチェックに依存しないこと、またはパッチ適用後に誰かが再起動していない場合に失敗することを心配しないのはいいことです。

関連する例として、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;
4
Erik Darling

All_viewsの代わりにsystem_viewsを使用できます。

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

これにより、ユーザー定義ビューを同時に選択することを回避できます。

1
Chessbrain