# 通知設計書 46-出力テーブル作成失敗

## 概要

本ドキュメントは、sp_BlitzIndexストアドプロシージャにおいて、出力テーブルの作成に失敗した場合に発生するエラー通知の設計を記載する。

### 本通知の処理概要

本通知は、分析結果の出力先テーブルを動的に作成しようとした際に、何らかの理由で作成が失敗した場合にエラーメッセージを出力し、処理を中断する機能を提供する。

**業務上の目的・背景**：sp_BlitzIndexは分析結果をテーブルに永続化する機能を提供している。出力先テーブルが存在しない場合、プロシージャは動的にテーブルを作成する。しかし、権限不足、ディスク容量不足、その他のシステムエラーにより作成が失敗する可能性がある。この場合、明確なエラーメッセージでユーザーに通知し、原因調査と対処を促す必要がある。

**通知の送信タイミング**：結果出力フェーズにおいて、テーブルが存在しないため新規作成を試みた後、再度テーブルの存在を確認し、作成が失敗していた場合（@TableExists != 1）に送信される。各モード（Mode 0/1/2/3）の結果出力セクションで個別にチェックされる。

**通知の受信者**：sp_BlitzIndexを実行したSQL Serverクライアントセッション。RAISERRORステートメントによりクライアントに直接エラーメッセージが返される。

**通知内容の概要**：エラーメッセージには、出力テーブルの作成が失敗したことが明示される。

**期待されるアクション**：ユーザーは通知内容を確認し、(1) CREATE TABLE権限があるか確認、(2) ディスク容量が十分か確認、(3) データベースが読み取り専用でないか確認、(4) 必要に応じて手動でテーブルを作成し再実行、のいずれかのアクションを取る。

## 通知種別

RAISERRORによるSQL Serverエラーメッセージ（クライアント通知）

## 送信仕様

### 基本情報

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

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

sp_BlitzIndexを実行したクライアントセッションに対して、RAISERRORステートメントにより直接エラーメッセージを送信する。

## 通知テンプレート

### エラーメッセージ

| 項目 | 内容 |
|-----|------|
| メッセージレベル | 16 |
| 状態 | 0 |
| 形式 | テキスト |

### 本文テンプレート

```
Creation of the output table failed.
```

### 添付ファイル

なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| なし | 固定メッセージのため変数なし | - | - |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| プロシージャ実行 | sp_BlitzIndex実行（Mode 0/1/2/3） | @TableExists = 0 でCREATE TABLE実行後も @TableExists != 1 | 結果出力フェーズで検出 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| @TableExists = 1の場合 | テーブルが既に存在または正常に作成された |
| @ValidOutputLocation = 0の場合 | 出力先が無効なため別の処理へ |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[結果出力フェーズ開始] --> B{@ValidOutputLocation = 1?}
    B -->|No| C[別の処理へ]
    B -->|Yes| D{@SchemaExists = 1?}
    D -->|No| E[RAISERROR: スキーマ名無効]
    D -->|Yes| F{@TableExists = 0?}
    F -->|No| G[既存テーブルにINSERT]
    F -->|Yes| H[CREATE TABLE実行]
    H --> I[テーブル存在再確認]
    I --> J{@TableExists = 1?}
    J -->|Yes| K[新規テーブルにINSERT]
    J -->|No| L[RAISERROR: 出力テーブル作成失敗]
    L --> M[RETURN - 処理中断]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| INFORMATION_SCHEMA.TABLES | テーブルの存在確認 | 動的SQL経由で参照 |

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

#### INFORMATION_SCHEMA.TABLES

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| TABLE_SCHEMA | スキーマ名照合 | WHERE QUOTENAME(TABLE_SCHEMA) = @OutputSchemaName |
| TABLE_NAME | テーブル名照合 | AND QUOTENAME(TABLE_NAME) = @OutputTableName |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| 動的に指定されるテーブル | CREATE TABLE | 出力テーブルの作成を試行（失敗時に本エラー発生） |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 出力テーブル作成失敗 | CREATE TABLE実行後もテーブルが存在しない | エラーメッセージを出力し処理中断 |

### リトライ仕様

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

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

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

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

- テーブル名をエラーメッセージに含めず、固定メッセージとすることでセキュリティリスクを低減
- CREATE TABLE権限が必要

## 備考

- テーブル作成は動的SQLで実行されるため、元のエラーメッセージは表示されない
- リンクサーバー経由の場合は、EXECで別サーバーにCREATE TABLEを実行する
- 同じエラーメッセージがsp_BlitzIndexの複数のモード（Mode 0, 1, 2, 3）で使用される

---

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

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

### 推奨読解順序

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

テーブル存在確認に関わる変数を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | sp_BlitzIndex.sql | `sp_BlitzIndex.sql` | @TableExists変数の宣言（行3718） |
| 1-2 | sp_BlitzIndex.sql | `sp_BlitzIndex.sql` | @TableExistsSql変数（テーブル存在確認用SQL）の定義 |

**読解のコツ**: @TableExistsはBIT型変数で、テーブル作成の前後で存在確認に使用される。

#### Step 2: テーブル存在確認ロジック

動的SQLによるテーブル存在確認の処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | sp_BlitzIndex.sql | `sp_BlitzIndex.sql` | テーブル存在確認の動的SQL設定（行3746-3749） |

**主要処理フロー**:
1. **行3746-3749**: @TableExistsSqlにINFORMATION_SCHEMA.TABLESを参照するSQLを設定
2. **行3743**: sp_executesqlで動的SQLを実行し、@TableExistsに結果を設定

#### Step 3: テーブル作成と再確認（Mode 0）

Mode 0でのテーブル作成と作成後の確認を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | sp_BlitzIndex.sql | `sp_BlitzIndex.sql` | Mode 0のテーブル作成セクション（行5939-5987） |

**主要処理フロー**:
1. **行5939**: IF @TableExists = 0 の条件判定
2. **行5941-5961**: CREATE TABLE文の動的SQL生成
3. **行5968-5976**: テーブル作成の実行（リンクサーバー or ローカル）
4. **行5980-5981**: テーブル存在の再確認
5. **行5983-5986**: IF NOT @TableExists = 1 → RAISERROR

#### Step 4: 他のモードでの実装確認

Mode 1, 2, 3での同様のチェックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | sp_BlitzIndex.sql | `sp_BlitzIndex.sql` | Mode 1の作成失敗チェック（行6152-6160） |
| 4-2 | sp_BlitzIndex.sql | `sp_BlitzIndex.sql` | Mode 2の作成失敗チェック（行6637-6639） |
| 4-3 | sp_BlitzIndex.sql | `sp_BlitzIndex.sql` | Mode 3の作成失敗チェック（行6871-6879） |

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

```
sp_BlitzIndex
    │
    ├─ パラメータ初期化
    │
    ├─ 出力先検証フェーズ
    │      └─ スキーマ/テーブル存在確認
    │
    ├─ メイン分析処理
    │
    └─ 結果出力フェーズ（各Mode共通）
           │
           ├─ @ValidOutputLocation = 1?
           │      │
           │      └─ @SchemaExists = 1?
           │             │
           │             └─ @TableExists = 0?
           │                    │
           │                    ├─ Yes → CREATE TABLE実行
           │                    │         │
           │                    │         └─ テーブル存在再確認
           │                    │                │
           │                    │                ├─ @TableExists = 1?
           │                    │                │      │
           │                    │                │      ├─ Yes → INSERT処理へ
           │                    │                │      │
           │                    │                │      └─ No → RAISERROR（本通知）
           │                    │                │               └─ RETURN
           │                    │
           │                    └─ No → 既存テーブルにINSERT
           │
           └─ 画面出力
```

### データフロー図

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

@TableExists = 0 ───▶ CREATE TABLE実行 ───▶ テーブル存在再確認
                              │                     │
                              │                     ▼
                              │             ┌─────────────────┐
                              │             │ EXEC sp_executesql │
                              │             │ @TableExistsSql   │
                              │             └─────────────────┘
                              │                     │
                              │                     ▼
                              │             @TableExists更新
                              │                     │
                              │       ┌─────────────┴─────────────┐
                              │       ▼                           ▼
                              │ [@TableExists = 1]         [@TableExists = 0]
                              │       │                           │
                              │       ▼                           ▼
                              │ INSERT処理へ           RAISERROR → クライアント
                              │                        "Creation of the output
                              │                         table failed."
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| sp_BlitzIndex.sql | `sp_BlitzIndex.sql` | ソース | インデックス分析プロシージャ、通知発生元（行5985, 6158, 6639, 6877） |
| Install-All-Scripts.sql | `Install-All-Scripts.sql` | ソース | 全スクリプトインストーラー（同一ロジック含む） |
| Install-Azure.sql | `Install-Azure.sql` | ソース | Azure用インストーラー（同一ロジック含む） |
