# 通知設計書 4-データベース読み取り不可

## 概要

本ドキュメントは、SQL Server First Responder Kit の sp_BlitzCache ストアドプロシージャにおいて、@DatabaseName パラメータで指定されたデータベースが読み取り不可能な状態にある場合に発生するエラー通知について定義する。

### 本通知の処理概要

本通知は、sp_BlitzCache プロシージャ実行時に指定されたデータベースが存在するものの、オフライン、復旧中、またはその他の理由で読み取りできない状態にある場合にエラーを発生させ、処理を中断するバリデーション機能である。

**業務上の目的・背景**：sp_BlitzCache はプランキャッシュを分析するツールであり、特定のデータベースでフィルタリングする場合、そのデータベースにアクセスできる必要がある。データベースがオフライン、単一ユーザーモード、復旧中、または読み取り専用でアクセス不可の場合、プランキャッシュの分析に必要なメタデータを取得できない。このエラー通知により、アクセス不可能なデータベースの指定を早期に検出する。

**通知の送信タイミング**：データベースの存在チェック（DB_ID()）に成功した後、DATABASEPROPERTYEX 関数を使用してデータベースの Collation プロパティを取得する。Collation が NULL の場合（データベースが読み取り不可の場合）に本エラーが発生する。ただし、Azure SQL DB (EngineEdition 5, 6, 8) の場合はこのチェックをスキップする。

**通知の受信者**：プロシージャを実行したユーザー（SQL Server セッションの呼び出し元）がエラーメッセージを受信する。

**通知内容の概要**：「The database you specified is not readable. Please check the name and try again. Better yet, check your server.」というメッセージで、データベースの状態確認を促す。

**期待されるアクション**：DBA に連絡してデータベースの状態を確認する。データベースがオフラインの場合はオンラインにする。復旧中の場合は復旧完了を待つ。必要に応じて別のデータベースを指定して再実行する。

## 通知種別

RAISERROR による SQL Server メッセージ出力（クライアントアプリケーションへの同期通知）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 高（Severity 16, State 1） |
| リトライ | なし（即時RETURN） |

### 送信先決定ロジック

プロシージャを実行したセッションに対して直接メッセージを送信する。送信先は固定であり、動的な決定ロジックは存在しない。

## 通知テンプレート

### メッセージ通知の場合

| 項目 | 内容 |
|-----|------|
| メッセージ形式 | RAISERROR |
| Severity | 16 |
| State | 1 |
| WITH句 | なし |

### 本文テンプレート

```
The database you specified is not readable. Please check the name and try again. Better yet, check your server.
```

### 添付ファイル

該当なし

## テンプレート変数

該当なし（固定メッセージ）

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| ストアドプロシージャ実行 | sp_BlitzCache の実行 | DATABASEPROPERTYEX(..., 'Collation') IS NULL かつ オンプレミス SQL Server | データベース読み取り可能性チェック |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| Azure SQL DB | SERVERPROPERTY('EngineEdition') IN (5, 6, 8) の場合はチェックをスキップ |
| データベースが読み取り可能 | Collation プロパティが NULL でない場合 |
| @DatabaseName が NULL | データベース名が指定されていない場合（'master' がデフォルトとして使用される） |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[データベース存在チェック通過] --> B{Azure SQL DB か?}
    B -->|Yes| C[チェックスキップ、処理続行]
    B -->|No| D[DATABASEPROPERTYEX で Collation 取得]
    D --> E{Collation が NULL か?}
    E -->|No| F[処理続行]
    E -->|Yes| G[RAISERROR 発行]
    G --> H[RETURN で処理終了]
    C --> I[メイン処理]
    F --> I
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| SERVERPROPERTY | エンジンエディション確認 | システム関数 |
| DATABASEPROPERTYEX | データベースプロパティ確認 | システム関数 |

### テーブル別参照項目詳細

#### DATABASEPROPERTYEX 関数

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| Collation | データベースの照合順序 | 読み取り可能性の間接確認 |

### 更新テーブル一覧

該当なし（エラー発生時は更新なし）

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| データベース読み取り不可 | データベースがオフライン、復旧中等 | DBA に連絡してデータベース状態を確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

該当なし（同期的なエラーメッセージ出力）

### 配信時間帯

制限なし（プロシージャ実行時に即時発生）

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

- データベース名はエラーメッセージに含まれないため、情報漏洩のリスクは低い
- データベースの可用性状態の情報は攻撃者にとって有用な可能性があるが、これは一般的なエラー処理パターン

## 備考

- sp_BlitzCache.sql の行1150-1154で定義されている
- ISNULL(@DatabaseName, 'master') により、@DatabaseName が NULL の場合は 'master' がデフォルトとして使用される
- Collation プロパティの取得は、データベースの読み取り可能性を間接的に確認する方法として使用されている

---

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

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

### 推奨読解順序

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

@DatabaseName パラメータとチェックロジックの関係を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | sp_BlitzCache.sql | `sp_BlitzCache.sql` | @DatabaseName パラメータ定義（行269） |

**読解のコツ**: ISNULL 関数により、NULL の場合は 'master' がデフォルト値として使用される点に注意。

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

バリデーションが実行されるタイミングを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | sp_BlitzCache.sql | `sp_BlitzCache.sql` | 読み取り可能性チェック（行1150-1154） |

**主要処理フロー**:
1. **行1150**: DATABASEPROPERTYEX で Collation を取得
2. **行1150**: ISNULL(@DatabaseName, 'master') でデフォルト値設定
3. **行1150**: SERVERPROPERTY('EngineEdition') NOT IN (5, 6, 8) で Azure 除外
4. **行1152**: RAISERROR でエラーメッセージ出力
5. **行1153**: RETURN で処理終了

#### Step 3: Azure SQL DB の処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | sp_BlitzCache.sql | `sp_BlitzCache.sql` | Azure SQL DB 専用の処理（行1140-1144） |

**主要処理フロー**:
- **行1140**: SERVERPROPERTY('EngineEdition') IN (5, 6) で Azure 判定
- **行1141**: DB_NAME() <> @DatabaseName でカレントDBとの比較
- **行1142**: Azure では異なるデータベースへの切り替え不可のエラーメッセージ

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

```
sp_BlitzCache (ストアドプロシージャ)
    │
    ├─ DB_ID(@DatabaseName)
    │      └─ データベース存在チェック（先行チェック）
    │
    ├─ SERVERPROPERTY('EngineEdition')
    │      └─ Azure SQL DB 判定（5, 6, 8 はスキップ）
    │
    ├─ DATABASEPROPERTYEX(@DatabaseName, 'Collation')
    │      └─ 読み取り可能性の間接チェック
    │
    └─ RAISERROR
           └─ エラーメッセージをクライアントに送信
```

### データフロー図

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

@DatabaseName ─────────▶ ISNULL(..., 'master') ──▶ 有効なDB名
       │
       ↓
       │
SERVERPROPERTY() ──────▶ EngineEdition 取得 ────▶ Azure判定
       │
       ↓ オンプレミスの場合
       │
       └───────────────▶ DATABASEPROPERTYEX() ──▶ Collation or NULL
                              │
                              ↓ NULL の場合
                              │
                              └───▶ RAISERROR ──▶ エラーメッセージ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| sp_BlitzCache.sql | `sp_BlitzCache.sql` | ソース | プランキャッシュ分析プロシージャ |
| Install-All-Scripts.sql | `Install-All-Scripts.sql` | ソース | 全スクリプトをまとめたインストールファイル |
| Install-Azure.sql | `Install-Azure.sql` | ソース | Azure SQL DB 向けインストールスクリプト |
