# 機能設計書 173-Invoke-DbaDiagnosticQuery

## 概要

本ドキュメントは、dbatools PowerShellモジュールのInvoke-DbaDiagnosticQuery関数の機能設計を定義する。Glenn BerryのDMV診断クエリを実行してSQL Serverのパフォーマンスと健全性を評価する機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：SQL Serverのパフォーマンス、構成、および健全性の問題を分析するためのDMVベースの包括的な診断クエリコレクションを実行する。ブロッキング、高CPU使用率、メモリプレッシャー、インデックス断片化、構成問題など、SQL Serverパフォーマンスに影響する一般的な問題を特定するために使用される。手動で複数のDMVをクエリする代わりに、構造化されたPowerShellオブジェクトとして結果を取得できる。

**機能の利用シーン**：
- SQL Serverインスタンスの定期的な健全性チェック
- パフォーマンス問題のトラブルシューティング
- アップグレード前後のシステム評価
- インフラストラクチャ監査とドキュメント作成
- 待機統計やCPU使用率の分析

**主要な処理内容**：
1. SQL Serverバージョンを検出し適切な診断クエリスクリプトを選択（2005-2025、Azure SQL Database対応）
2. 指定されたデータベースまたは全ユーザーデータベースに対してクエリを実行
3. インスタンスレベルまたはデータベースレベルの診断を選択的に実行
4. 結果をPSCustomObjectとして構造化して出力
5. オプションでSQLファイルとしてエクスポート

**関連システム・外部連携**：Glenn Berryの診断クエリスクリプト（dbatools/bin/diagnosticquery/に同梱）。外部URLからのスクリプト取得も可能。

**権限による制御**：多くの診断クエリにはVIEW SERVER STATE権限が必要。一部のクエリにはsysadmin権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面機能マッピングに登録なし |

## 機能種別

診断 / パフォーマンス分析

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | Yes | ターゲットSQL Serverインスタンス | Mandatory, ValueFromPipeline |
| SqlCredential | PSCredential | No | 接続資格情報 | - |
| Path | FileInfo | No | カスタム診断クエリスクリプトのパス | - |
| Database | object[] | No | 診断対象データベース | ワイルドカード対応 |
| ExcludeDatabase | object[] | No | 除外するデータベース | - |
| ExcludeQuery | object[] | No | 除外する診断クエリ | - |
| UseSelectionHelper | switch | No | インタラクティブなクエリ選択グリッドを表示 | - |
| QueryName | string[] | No | 実行する特定のクエリ名 | - |
| InstanceOnly | switch | No | インスタンスレベルのクエリのみ実行 | - |
| DatabaseSpecific | switch | No | データベースレベルのクエリのみ実行 | - |
| ExcludeQueryTextColumn | switch | No | クエリテキスト列を除外 | - |
| ExcludePlanColumn | switch | No | クエリプラン列を除外 | - |
| NoColumnParsing | switch | No | 列のパースを無効化 | - |
| OutputPath | string | No | エクスポート先ディレクトリ | - |
| ExportQueries | switch | No | SQLファイルとしてエクスポート | - |
| EnableException | switch | No | 例外をスローするか | - |

### 入力データソース

- SqlInstanceパラメータで指定されたSQL Serverインスタンス
- dbatools/bin/diagnosticquery/配下の診断クエリスクリプトファイル
- カスタムPathで指定された診断クエリスクリプト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverインスタンスのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| Number | int | Glenn Berryの診断クエリコレクションのクエリ番号 |
| Name | string | 診断クエリの名前またはタイトル |
| Description | string | クエリの説明 |
| DatabaseSpecific | bool | データベース固有クエリかどうか |
| Database | string | データベース名（DBSpecific=trueの場合） |
| Notes | string | ステータスノート（空結果、WhatIf時など） |
| Result | DataRow[] | クエリ結果セット |

### 出力先

- 標準出力（パイプライン）にPSCustomObjectを出力
- ExportQueriesモードではOutputPathにSQLファイルを出力

## 処理フロー

### 処理シーケンス

```
1. beginブロック: 診断クエリスクリプトの読み込み
   ├─ Pathが指定されていない場合はモジュール内蔵スクリプトを使用
   ├─ 最新日付のスクリプトファイルを選択
   └─ スクリプトをパースしてバージョン別に格納

2. processブロック開始
   ├─ 各インスタンスに対して接続
   └─ SQL Serverバージョンを検出

3. バージョン判定
   ├─ SQL Server 2005-2025、Azure SQL Databaseに対応
   └─ 適切なバージョンのスクリプトを選択

4. UseSelectionHelper処理（指定時）
   └─ Out-GridViewでクエリ選択ダイアログを表示

5. クエリ実行ループ
   ├─ 各クエリに対して実行判定
   ├─ ExportQueriesモードの場合はファイル出力
   ├─ インスタンスレベルクエリを実行
   └─ データベースレベルクエリを各DBに対して実行

6. 結果オブジェクト構築・出力
   └─ PSCustomObjectとしてパイプライン出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[スクリプトファイル読み込み]
    B --> C[バージョン別スクリプト格納]
    C --> D{インスタンスループ}
    D -->|次のInstance| E[Connect-DbaInstance]
    E --> F[SQL Serverバージョン検出]
    F --> G[適切なスクリプト選択]
    G --> H{UseSelectionHelper?}
    H -->|Yes| I[Out-GridViewで選択]
    H -->|No| J{クエリループ}
    I --> J
    J -->|次のQuery| K{ExportQueries?}
    K -->|Yes| L[SQLファイル出力]
    K -->|No| M{DBSpecific?}
    L --> J
    M -->|No| N[クエリ実行]
    M -->|Yes| O{DBループ}
    O -->|次のDB| P[クエリ実行]
    N --> Q[結果オブジェクト出力]
    P --> Q
    Q --> J
    J -->|完了| D
    D -->|完了| R[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-173-01 | バージョン自動検出 | SQL Serverバージョンを自動検出し適切なスクリプトを選択 | 常時 |
| BR-173-02 | 最新スクリプト使用 | 同一バージョンで複数日付のスクリプトがある場合、最新を使用 | 常時 |
| BR-173-03 | システムDB除外 | データベースレベルクエリではシステムDBを自動除外 | DatabaseSpecific時 |
| BR-173-04 | Azure SQL Database対応 | Azure SQL DatabaseではAzureDatabase用スクリプトを使用 | Azure SQL DB接続時 |

### 計算ロジック

バージョン判定ロジック:
```powershell
switch ($server.VersionMajor) {
    9 { "2005" }
    10 { "2008" }
    11 { "2012" }
    12 { "2014" }
    13 { "2016" }
    14 { "2017" }
    15 { "2019" }
    16 { "2022" }
    17 { "2025" }
}
```

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 診断クエリ実行 | DMV各種 | SELECT | 読み取り専用クエリ |

### テーブル別操作詳細

診断クエリは全て読み取り専用であり、データベースに変更を加えない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ConnectionError | インスタンスへの接続失敗 | 接続情報を確認 |
| - | ScriptNotFound | 診断スクリプトが見つからない | Pathを確認またはインターネット接続を確認 |
| - | QueryError | 個別クエリの実行エラー | 権限を確認、エラーメッセージをログ出力 |

### リトライ仕様

リトライ機能は実装されていない。個別クエリでエラーが発生した場合はログ出力して次のクエリに進む。

## トランザクション仕様

全て読み取り専用クエリのため、トランザクション管理は不要。

## パフォーマンス要件

- 大規模データベースでのインデックス断片化クエリは時間がかかる可能性
- ExcludeQueryで時間のかかるクエリを除外可能
- ExcludePlanColumnでメモリ使用量を削減可能

## セキュリティ考慮事項

- VIEW SERVER STATE権限が必要
- 一部のクエリにはsysadmin権限が必要
- SqlCredentialによる安全な認証をサポート

## 備考

- Glenn Berryの診断クエリは定期的に更新される
- カスタムPathで最新版のスクリプトを使用可能
- Export-DbaDiagnosticQueryと組み合わせてCSV/Excelエクスポート可能

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

出力オブジェクトの構造と診断クエリスクリプトの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Invoke-DbaDiagnosticQuery.ps1 | `public/Invoke-DbaDiagnosticQuery.ps1` | 364-395行目: 出力PSCustomObjectの構造 |

**読解のコツ**: Number, Name, Description, DatabaseSpecific, Result各プロパティの意味を理解する。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Invoke-DbaDiagnosticQuery.ps1 | `public/Invoke-DbaDiagnosticQuery.ps1` | 関数全体の流れを把握 |

**主要処理フロー**:
1. **190-243行目**: beginブロックでスクリプトファイル読み込みとパース
2. **245-254行目**: インスタンス接続
3. **256-284行目**: SQL Serverバージョン検出とスクリプト選択
4. **296-308行目**: UseSelectionHelperでのクエリ選択
5. **339-498行目**: クエリ実行ループとDatabase-specificクエリ処理

#### Step 3: バージョン判定ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Invoke-DbaDiagnosticQuery.ps1 | `public/Invoke-DbaDiagnosticQuery.ps1` | 257-284行目: バージョン判定ロジック |

**主要処理フロー**:
- **257-270行目**: VersionMajorからバージョン文字列への変換
- **273-280行目**: SQL Server 2016のSP判定
- **282-284行目**: Azure SQL Databaseの判定

### プログラム呼び出し階層図

```
Invoke-DbaDiagnosticQuery
    │
    ├─ beginブロック
    │      ├─ Get-ChildItem (スクリプトファイル取得)
    │      └─ Invoke-DbaDiagnosticQueryScriptParser
    │
    ├─ processブロック
    │      ├─ Connect-DbaInstance
    │      ├─ Get-DbaDatabase (DB一覧取得)
    │      ├─ Invoke-DiagnosticQuerySelectionHelper (オプション)
    │      │      └─ Out-GridView
    │      └─ server.Query (各診断クエリ実行)
    │
    └─ endブロック
           └─ Write-Progress (完了)
```

### データフロー図

```
[入力]                          [処理]                              [出力]

bin/diagnosticquery/*.sql ─▶ スクリプトパース ─▶ $scriptversions
                                    │
SqlInstance ──────────────▶ Connect-DbaInstance
                                    │
                                    ▼
                          バージョン判定・スクリプト選択
                                    │
                                    ▼
                    ┌───────────────┴───────────────┐
                    ▼                               ▼
            [InstanceOnly]                  [DatabaseSpecific]
                    │                               │
                    ▼                               ▼
           server.Query()                  各DBに対してQuery()
                    │                               │
                    └─────────────┬─────────────────┘
                                  ▼
                           PSCustomObject[]
                                  │
                    ┌─────────────┴─────────────┐
                    ▼                           ▼
              パイプライン出力           SQLファイルエクスポート
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Invoke-DbaDiagnosticQuery.ps1 | `public/Invoke-DbaDiagnosticQuery.ps1` | ソース | メイン関数 |
| SQLServerDiagnosticQueries_*.sql | `bin/diagnosticquery/` | スクリプト | Glenn Berryの診断クエリ |
| Invoke-DbaDiagnosticQueryScriptParser.ps1 | `private/functions/` | ソース | スクリプトパーサー |
| Export-DbaDiagnosticQuery.ps1 | `public/Export-DbaDiagnosticQuery.ps1` | ソース | 結果エクスポート |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続処理 |
| Get-DbaDatabase.ps1 | `public/Get-DbaDatabase.ps1` | ソース | データベース一覧取得 |
