# 機能設計書 10-sp_ineachdb

## 概要

本ドキュメントは、SQL Server First Responder Kitのsp_ineachdbストアドプロシージャの機能設計について記載する。sp_ineachdbは指定したコマンドを複数のデータベースで順次実行するユーティリティである。

### 本機能の処理概要

sp_ineachdbは、sp_MSforeachdbの代替として設計された、複数データベースに対してコマンドを実行するストアドプロシージャである。フィルタリング条件を豊富に備え、より安全で柔軟な実行が可能。

**業務上の目的・背景**：sp_MSforeachdbは非公開のシステムプロシージャであり、いくつかのデータベースをスキップする問題がある。sp_ineachdbはこれを解決し、より信頼性の高い複数データベース操作を提供する。

**機能の利用シーン**：
- 全データベースに対する統計更新
- 全データベースの整合性チェック
- 特定条件に合致するデータベースへのスキーマ変更
- 複数データベースからの情報収集

**主要な処理内容**：
1. 対象データベースのフィルタリング
2. データベースコンテキストでのコマンド実行
3. エラーハンドリングと継続処理

**関連システム・外部連携**：
- sys.databases
- sys.dm_hadr_database_replica_states（AG環境）
- sys.availability_replicas（AG環境）

**権限による制御**：
- 対象データベースへのアクセス権が必要
- 実行コマンドに応じた権限が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 13 | sp_ineachdb結果画面 | 主機能 | 指定コマンドを複数データベースで順次実行 |

## 機能種別

運用ユーティリティ / バッチ処理 / 自動化ツール

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| @command | NVARCHAR(MAX) | No | 実行するコマンド | NULL許可 |
| @replace_character | NCHAR(1) | No | DB名置換文字 | デフォルト'?' |
| @print_dbname | BIT | No | DB名をPRINT出力 | デフォルト0 |
| @select_dbname | BIT | No | DB名をSELECT出力 | デフォルト0 |
| @print_command | BIT | No | コマンドをPRINT出力 | デフォルト0 |
| @print_command_only | BIT | No | 出力のみ（実行しない） | デフォルト0 |
| @suppress_quotename | BIT | No | QUOTENAME抑制 | デフォルト0 |
| @system_only | BIT | No | システムDBのみ | デフォルト0 |
| @user_only | BIT | No | ユーザーDBのみ | デフォルト0 |
| @name_pattern | NVARCHAR(300) | No | DB名パターン（LIKE） | デフォルト'%' |
| @database_list | NVARCHAR(MAX) | No | 対象DBリスト（CSV） | NULL許可 |
| @exclude_pattern | NVARCHAR(300) | No | 除外パターン（LIKE） | NULL許可 |
| @exclude_list | NVARCHAR(MAX) | No | 除外DBリスト（CSV） | NULL許可 |
| @recovery_model_desc | NVARCHAR(120) | No | リカバリモデルフィルタ | NULL許可 |
| @compatibility_level | TINYINT | No | 互換性レベルフィルタ | NULL許可 |
| @state_desc | NVARCHAR(120) | No | 状態フィルタ | デフォルト'ONLINE' |
| @is_read_only | BIT | No | 読み取り専用フィルタ | デフォルト0 |
| @is_auto_close_on | BIT | No | 自動クローズフィルタ | NULL許可 |
| @is_auto_shrink_on | BIT | No | 自動圧縮フィルタ | NULL許可 |
| @is_broker_enabled | BIT | No | Service Brokerフィルタ | NULL許可 |
| @user_access | NVARCHAR(128) | No | ユーザーアクセスフィルタ | NULL許可 |
| @Help | BIT | No | ヘルプ表示 | デフォルト0 |
| @Version | VARCHAR(30) | No | バージョン（OUTPUT） | 出力専用 |
| @VersionDate | DATETIME | No | バージョン日付（OUTPUT） | 出力専用 |
| @VersionCheckMode | BIT | No | バージョンチェックモード | デフォルト0 |
| @is_ag_writeable_copy | BIT | No | AG書き込み可能コピーのみ | デフォルト0 |
| @is_query_store_on | BIT | No | Query Storeフィルタ | NULL許可 |

### 入力データソース

- sys.databases: データベース一覧と属性
- sys.dm_hadr_database_replica_states: AG状態
- sys.availability_replicas: AGレプリカ情報
- sys.dm_hadr_availability_group_states: AG状態

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ineachdb current database | sysname | 現在処理中のDB名（@select_dbname=1時） |
| コマンド結果 | 可変 | 実行コマンドの出力 |

### 出力先

- 画面表示（コマンド実行結果）
- PRINT出力（@print_dbname=1または@print_command=1時）

## 処理フロー

### 処理シーケンス

```
1. パラメータ検証と初期化
   └─ バージョンチェック

2. 対象データベース収集
   ├─ @database_listの解析（CSV分割）
   ├─ @exclude_listの解析（CSV分割）
   └─ #ineachdb一時テーブルに格納

3. フィルタリング
   ├─ @system_only/@user_onlyフィルタ
   ├─ @name_pattern/@exclude_patternフィルタ
   ├─ 属性フィルタ（recovery_model等）
   ├─ 状態フィルタ（ONLINE/アクセス可能）
   └─ AG関連フィルタ

4. データベースループ
   ├─ DB名置換（@replace_character）
   ├─ コマンド出力（オプション）
   └─ コマンド実行（sp_executesql）

5. エラーハンドリング
   └─ TRY-CATCHで継続処理
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{@Help = 1?}
    B -->|Yes| C[ヘルプ出力]
    C --> Z[終了]
    B -->|No| D[#ineachdb作成]
    D --> E{@database_list指定?}
    E -->|Yes| F[CSV分割・INSERT]
    E -->|No| G[全DB INSERT]
    F --> H[除外リスト処理]
    G --> H
    H --> I[属性フィルタ適用]
    I --> J[状態フィルタ適用]
    J --> K[AGフィルタ適用]
    K --> L{対象DBあり?}
    L -->|No| M[警告・終了]
    L -->|Yes| N[カーソルオープン]
    N --> O{FETCH成功?}
    O -->|No| P[カーソルクローズ]
    P --> Z
    O -->|Yes| Q[DB名置換]
    Q --> R{@print_command_only?}
    R -->|Yes| S[コマンドPRINT]
    R -->|No| T[sp_executesql実行]
    S --> U[次のDB]
    T --> U
    U --> O
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 置換文字 | @replace_characterをDB名で置換 | 常時 |
| BR-002 | QUOTENAME | デフォルトでDB名をQUOTENAME | @suppress_quotename=0 |
| BR-003 | システムDB | ID 1,2,3,4またはis_distributor=1 | @system_only=1 |
| BR-004 | 除外優先 | @exclude_listは@database_listより優先 | 常時 |
| BR-005 | ONLINE必須 | デフォルトでONLINE状態のみ | @state_desc='ONLINE' |
| BR-006 | アクセス確認 | HAS_DBACCESS=1のDBのみ | 常時 |
| BR-007 | AG読み取り不可スキップ | secondary_role_allow_connections=0のDBをスキップ | AG環境 |

### 計算ロジック

**DB名置換**:
```sql
SET @cmd = REPLACE(@command, @replace_character, REPLACE(@thisdb,'''',''''''));
```

**CSV分割（再帰CTE）**:
```sql
WITH BackupPaths AS (
  SELECT 1 AS StartPosition,
    ISNULL(NULLIF(CHARINDEX(',', @database_list, 1), 0), LEN(@database_list) + 1) AS EndPosition,
    SUBSTRING(@database_list, 1, ...) AS PathItem
  ...
)
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 参照 | sys.databases | SELECT | データベース一覧取得 |
| 参照 | sys.dm_hadr_database_replica_states | SELECT | AGレプリカ状態 |
| 参照 | sys.availability_replicas | SELECT | AGレプリカ情報 |
| 参照 | sys.dm_hadr_availability_group_states | SELECT | AG状態 |
| 実行 | 可変 | 可変 | @commandで指定されたコマンド |

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

#### #ineachdb（一時テーブル）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | id | database_id | DBID |
| INSERT | name | name | DB名 |
| INSERT | is_distributor | is_distributor | ディストリビュータフラグ |
| DELETE | - | 各種フィルタ条件 | フィルタリング |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 対象なし | フィルタ後に対象DBなし | RAISERRORで警告、RETURN |
| - | 実行エラー | コマンド実行失敗 | CATCHで捕捉、警告出力、次DBへ継続 |

### リトライ仕様

特定のリトライ機能は実装されていない。エラー発生時は次のデータベースへ継続。

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

明示的なトランザクション制御は行われない。各データベースへのコマンドは個別に実行。

## パフォーマンス要件

- データベース数に比例して実行時間が増加
- 各コマンドの実行時間に依存

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

- 対象データベースへのアクセス権が必要
- @suppress_quotename=1は慎重に使用（SQLインジェクションリスク）
- 実行コマンドに応じた権限が必要

## 備考

- バージョン: 8.29（2026年2月3日時点）
- sp_MSforeachdbの代替として設計
- SQL Server 2016以降でQuery Storeフィルタ対応
- Availability Group環境での安全な動作をサポート

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | sp_ineachdb.sql | `sp_ineachdb.sql` | **111行目**: #ineachdb一時テーブル定義 |

**読解のコツ**: #ineachdbは対象データベースIDと名前を格納するシンプルな構造。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | sp_ineachdb.sql | `sp_ineachdb.sql` | **5-34行目**: ALTER PROCEDURE定義とパラメータ |
| 2-2 | sp_ineachdb.sql | `sp_ineachdb.sql` | **36-45行目**: 初期設定とバージョンチェック |
| 2-3 | sp_ineachdb.sql | `sp_ineachdb.sql` | **47-97行目**: @Help=1時のヘルプ出力 |

**主要処理フロー**:
1. **37-38行目**: SET NOCOUNT ON、STATISTICS XML OFF
2. **40行目**: バージョン情報設定（8.29）
3. **99-108行目**: 変数宣言

#### Step 3: データベースリスト処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | sp_ineachdb.sql | `sp_ineachdb.sql` | **165-216行目**: CSV分割ロジック（再帰CTE） |

**主要処理フロー**:
- **165-171行目**: CTE初期化（@database_listと@exclude_listを同時処理）
- **172-196行目**: 再帰CTEでCSV分割（括弧内のカンマを考慮）
- **207-216行目**: sys.databasesとJOINしてINSERT

#### Step 4: フィルタリング処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | sp_ineachdb.sql | `sp_ineachdb.sql` | **217-237行目**: 属性フィルタ |
| 4-2 | sp_ineachdb.sql | `sp_ineachdb.sql` | **239-254行目**: Query Storeフィルタ |
| 4-3 | sp_ineachdb.sql | `sp_ineachdb.sql` | **256-261行目**: ユーザーアクセスフィルタ |
| 4-4 | sp_ineachdb.sql | `sp_ineachdb.sql` | **263-281行目**: 状態・アクセス可能性フィルタ |
| 4-5 | sp_ineachdb.sql | `sp_ineachdb.sql` | **283-315行目**: AGフィルタ |

**主要処理フロー**:
- **218-221行目**: @system_only/@user_onlyフィルタ
- **221-222行目**: @name_pattern/@exclude_patternフィルタ
- **223-237行目**: 各種属性フィルタ（COALESCE使用）

#### Step 5: コマンド実行ループを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | sp_ineachdb.sql | `sp_ineachdb.sql` | **317-322行目**: 対象なしチェック |
| 5-2 | sp_ineachdb.sql | `sp_ineachdb.sql` | **324-331行目**: カーソル定義とオープン |
| 5-3 | sp_ineachdb.sql | `sp_ineachdb.sql` | **336-370行目**: 実行ループ |

**主要処理フロー**:
- **338行目**: @replace_character置換
- **341-345行目**: @print_dbname処理
- **352-355行目**: @print_command処理
- **357-361行目**: sp_executesql実行
- **364-367行目**: エラーハンドリング

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

```
sp_ineachdb
    │
    ├─ #ineachdb一時テーブル作成
    │
    ├─ データベースリスト収集
    │   ├─ @database_list CSV分割（再帰CTE）
    │   ├─ @exclude_list CSV分割（再帰CTE）
    │   └─ sys.databases からINSERT
    │
    ├─ フィルタリング（DELETE）
    │   ├─ @system_only / @user_only
    │   ├─ @name_pattern / @exclude_pattern
    │   ├─ 属性フィルタ（recovery_model等）
    │   ├─ @is_query_store_on（SQL 2016+）
    │   ├─ @user_access
    │   ├─ 状態・アクセス可能性
    │   └─ AG関連フィルタ
    │
    ├─ カーソルループ
    │   ├─ DB名置換（@replace_character）
    │   ├─ PRINT出力（オプション）
    │   └─ sp_executesql実行
    │
    └─ エラーハンドリング
        └─ TRY-CATCHで継続
```

### データフロー図

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

パラメータ ──────────────────▶ パラメータ検証 ─────────────────▶
   │                              │
   │                              ▼
@database_list ──────────────▶ CSV分割（CTE） ─────────────────▶ #ineachdb
   │                              │
@exclude_list ───────────────▶ CSV分割（CTE） ─────────────────▶ │
   │                              │                                   │
sys.databases ───────────────▶ JOIN ──────────────────────────────▶ │
                                  │
                                  ▼
                            フィルタリング（DELETE）
                                  │
                                  ├─ @system_only / @user_only
                                  ├─ @name_pattern / @exclude_pattern
                                  ├─ 属性フィルタ
                                  ├─ 状態フィルタ
                                  └─ AGフィルタ
                                  │
                                  ▼
                            カーソルループ
                                  │
@command ────────────────────▶ 置換処理 ───────────────────────▶
                                  │
                                  ▼
                            sp_executesql ─────────────────────▶ コマンド結果
                                  │
                                  ▼
                            エラーハンドリング ─────────────────▶ 警告メッセージ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| sp_ineachdb.sql | `sp_ineachdb.sql` | ソース | メインストアドプロシージャ定義 |
