Erin Stellato の推奨設定でQuery Storeの使用を開始したいと思います。
USE [master]
GO
ALTER DATABASE DatabaseName SET QUERY_STORE = ON
GO
ALTER DATABASE DatabaseName SET QUERY_STORE (OPERATION_MODE = READ_WRITE
, INTERVAL_LENGTH_MINUTES = 30
, MAX_STORAGE_SIZE_MB = 1000
, QUERY_CAPTURE_MODE = AUTO)
GO
しかし、それはデータベースごとの設定であり、インスタンスのすべてのデータベースで一度にアクティブ化できるようにしたいと考えています。
set RECOVERY Model using sp_msforeachdb(at serverfault)
OPのソリューションを使用できます
EXECUTE master.sys.sp_MSforeachdb 'USE [?];
IF DB_ID() >= 5
ALTER DATABASE [?] SET QUERY_STORE = ON
ALTER DATABASE [?] SET QUERY_STORE (OPERATION_MODE = READ_WRITE
, INTERVAL_LENGTH_MINUTES = 30
, MAX_STORAGE_SIZE_MB = 1000
, QUERY_CAPTURE_MODE = AUTO)
'
動作している間、エラーが発生します
メッセージ12438、レベル16、状態1、行41
システムデータベースマスターでクエリストアを有効にできないため、アクションを実行できません。
メッセージ5069、レベル16、状態1、行41
ALTER DATABASEステートメントが失敗しました。
メッセージ12438、レベル16、状態1、行41
システムデータベースtempdbでクエリストアを有効にできないため、アクションを実行できません。
メッセージ5069、レベル16、状態1、行41
ALTER DATABASEステートメントが失敗しました。
Jason Cumberland によるソリューションのいくつかのバリエーションを試しましたが、機能しませんでした。
set quoted_identifier on
EXECUTE master.sys.sp_MSforeachdb '
IF '?' not in ('tempdb','master','model')
begin
exec (ALTER DATABASE [?] SET QUERY_STORE = ON
ALTER DATABASE [?] SET QUERY_STORE (OPERATION_MODE = READ_WRITE
, INTERVAL_LENGTH_MINUTES = 30
, MAX_STORAGE_SIZE_MB = 1000
, QUERY_CAPTURE_MODE = AUTO))
end
'
エラーが出ます
メッセージ102、レベル15、状態1、行25
「?」付近の構文が正しくありません。
これら二つは働く
--Turn off on all databases
EXECUTE master.sys.sp_MSforeachdb 'USE [?]; ALTER DATABASE [?] SET QUERY_STORE = OFF'
そして
--Check all Query Store database settings at once
EXECUTE master.sys.sp_MSforeachdb 'USE [?]; SELECT * FROM sys.database_query_store_options'
質問:エラーメッセージを表示せずにインスタンスのすべてのデータベースでクエリストアを有効にするにはどうすればよいですか?
注:システムデータベースのmsdbは、クエリストアを許可する唯一のデータベースです。現在は除外していません。
SQL 2016(SP1)を実行しているSQLインスタンスに対してSSMS 17.4を使用しています
質問で試行されたクエリのどちらの場合も、問題は単に構文上のものです。
最初のケース:IF
条件がありますが、その後のステートメントをグループ化しないでください。そのため、IF
の直後のステートメントのみが条件付きです。 2番目の_ALTER DATABASE
_ステートメントは常に実行されます。修正するには、次のようにします。
_EXECUTE master.sys.sp_MSforeachdb N'USE [?];
IF DB_ID() >= 5
BEGIN
ALTER DATABASE [?] SET QUERY_STORE = ON;
ALTER DATABASE [?] SET QUERY_STORE
(OPERATION_MODE = READ_WRITE,
INTERVAL_LENGTH_MINUTES = 30,
MAX_STORAGE_SIZE_MB = 1000,
QUERY_CAPTURE_MODE = AUTO);
END;
';
_
また、おそらくUSE
ステートメントも必要ありません。削除してから、DB_ID()
をDB_ID(N''?'')
に変更できます。
2番目のケース:埋め込まれた単一引用符をエスケープしませんでした。また、無関係なEXEC
があり、msdb
システムデータベースが含まれていませんでした。これらすべてを修正するには、次の手順を実行します。
_EXECUTE master.sys.sp_MSforeachdb N'
IF (N''?'' NOT IN (N''tempdb'', N''master'', N''model'', N''msdb''))
BEGIN
ALTER DATABASE [?] SET QUERY_STORE = ON;
ALTER DATABASE [?] SET QUERY_STORE
(OPERATION_MODE = READ_WRITE,
INTERVAL_LENGTH_MINUTES = 30,
MAX_STORAGE_SIZE_MB = 1000,
QUERY_CAPTURE_MODE = AUTO);
END;
';
_
注: @Krisは、「_sp_MSForeachDB
_は文書化されておらず、サポートされていない」と言っても不正確ではありません。別のメカニズムを使用してDBを循環することをお勧めします。これが1回限りのタスクであれば問題はありませんが、このコードを繰り返し使用する場合は、その警告に注意する必要があります。
最初、 sp_MSForeachDB
はドキュメント化もサポートもされていないため、使用を中止してください。実際に、実際のシナリオでDBが完全に欠落しているのを見てきました。
Aaron Bertrand DBを見逃さないはるかに優れたバージョンがあります 、私は問題なくかなり長い間使用してきました。
DB内をカーソルで移動したくない場合は、古き良きダイナミックSQLを常に使用してスクリプトを生成し、手動で実行することができます。
SELECT 'ALTER DATABASE '
+QUOTENAME(name)+
' SET QUERY_STORE = ON;'
FROM sys.databases where database_id>4