# 機能設計書 660-Find-DbaStoredProcedure

## 概要

本ドキュメントは、dbatools PowerShellモジュールの `Find-DbaStoredProcedure` 関数の機能設計を記述するものである。本機能はSQL Serverデータベース全体のストアドプロシージャ定義内で特定のテキストパターンや正規表現を検索するコマンドレットである。

### 本機能の処理概要

**業務上の目的・背景**：
大規模なデータベース環境では、数百から数千のストアドプロシージャが存在することがある。ハードコードされた値、非推奨の関数呼び出し、セキュリティの脆弱性、特定のビジネスロジックなどを特定する際に、プロシージャ定義内を検索する必要がある。本機能は sys.sql_modules を検索し、パターンにマッチするプロシージャを特定して、マッチした行番号とコンテキストを含む結果を返す。

**機能の利用シーン**：
- ハードコードされた値（接続文字列、サーバー名など）の検索
- 非推奨関数（例：RAISERROR、xp_cmdshell）の使用箇所特定
- セキュリティ監査（SQL インジェクション脆弱性の検出）
- コード標準化のためのパターン検出
- 特定ビジネスロジックの使用箇所調査

**主要な処理内容**：
1. SQL Serverインスタンスへの接続
2. 対象データベースのフィルタリング（Database/ExcludeDatabase）
3. sys.sql_modules からプロシージャ定義の取得
4. 正規表現によるパターンマッチング
5. マッチ行の行番号とテキストの抽出
6. 結果オブジェクトの出力

**関連システム・外部連携**：
- SQL Server DMV (sys.sql_modules, sys.procedures)
- SMO StoredProcedure オブジェクト
- PowerShell Select-String による正規表現マッチング

**権限による制御**：
- 対象データベースへの読み取り権限が必要
- sys.sql_modules へのアクセス権限が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLI (PowerShell) | 主画面 | コマンドライン実行によるパターン検索 |

## 機能種別

データ取得処理（SELECT） / 検索処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | Yes | 対象SQL Serverインスタンス | 必須、パイプライン入力可 |
| SqlCredential | PSCredential | No | SQL Server接続用資格情報 | - |
| Database | object[] | No | 対象データベース名 | - |
| ExcludeDatabase | object[] | No | 除外データベース名 | - |
| Pattern | string | Yes | 検索パターン（正規表現対応） | 必須 |
| IncludeSystemObjects | switch | No | システムプロシージャを含む | - |
| IncludeSystemDatabases | switch | No | システムデータベースを含む | - |
| EnableException | switch | No | 例外処理の有効化 | - |

### 入力データソース

- PowerShellコマンドラインからのパラメータ入力
- SQL Server sys.sql_modules からのプロシージャ定義

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | コンピュータ名 |
| SqlInstance | string | インスタンス名 |
| Database | string | データベース名 |
| DatabaseId | int | データベースID |
| Schema | string | スキーマ名 |
| Name | string | プロシージャ名 |
| Owner | string | オーナー名 |
| IsSystemObject | bool | システムオブジェクトか |
| CreateDate | datetime | 作成日時 |
| LastModified | datetime | 最終更新日時 |
| StoredProcedureTextFound | string | マッチ行（行番号付き） |
| StoredProcedure | object | SMO StoredProcedure オブジェクト（非表示） |
| StoredProcedureFullText | string | 完全なプロシージャ定義（非表示） |

### 出力先

PowerShellパイプライン（マッチしたプロシージャごとに1オブジェクト）

## 処理フロー

### 処理シーケンス

```
1. 初期化処理（beginブロック）
   └─ SQLクエリの構築
   └─ IncludeSystemObjects に応じたWHERE句追加

2. メイン処理（processブロック）
   └─ 各SQL Serverインスタンスに対して処理
       └─ SQL Serverへの接続
       └─ バージョンチェック（SQL Server 2005以上）
       └─ データベース一覧の取得とフィルタリング
       └─ 各データベースの処理
           └─ SQLクエリ実行（sys.sql_modules + sys.procedures）
           └─ 各プロシージャのパターンマッチング
           └─ マッチ時：行番号抽出と結果オブジェクト生成
           └─ 結果出力

3. 終了処理（endブロック）
   └─ 処理統計の出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[SQLクエリ構築]
    B --> C{IncludeSystemObjects?}
    C -->|No| D[WHERE is_ms_shipped=0追加]
    C -->|Yes| E[全プロシージャ対象]
    D --> F[各SqlInstanceをループ]
    E --> F
    F --> G[SQL Server接続]
    G --> H{バージョン >= 2005?}
    H -->|No| I[警告: 非対応バージョン]
    H -->|Yes| J{IncludeSystemDatabases?}
    J -->|No| K[ユーザーDBのみ]
    J -->|Yes| L[全DBを対象]
    K --> M[Database/ExcludeDBフィルタ適用]
    L --> M
    M --> N[各データベースをループ]
    N --> O[SQLクエリ実行]
    O --> P[各プロシージャをループ]
    P --> Q{Pattern にマッチ?}
    Q -->|No| R[スキップ]
    Q -->|Yes| S[SMOオブジェクト取得]
    S --> T[行分割・Select-String]
    T --> U[行番号付きマッチ行抽出]
    U --> V[結果オブジェクト生成・出力]
    V --> W{次のプロシージャ?}
    R --> W
    W -->|Yes| P
    W -->|No| X{次のデータベース?}
    X -->|Yes| N
    X -->|No| Y{次のインスタンス?}
    Y -->|Yes| F
    Y -->|No| Z[処理統計出力]
    Z --> AA[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | システムプロシージャ除外 | デフォルトでis_ms_shipped = 0のプロシージャのみ | IncludeSystemObjects未指定時 |
| BR-002 | システムDB除外 | デフォルトでIsSystemObject = falseのDBのみ | IncludeSystemDatabases未指定時 |
| BR-003 | 正規表現対応 | Patternは正規表現として解釈 | 常時 |
| BR-004 | 最小バージョン要件 | SQL Server 2005以上 | バージョンチェック時 |
| BR-005 | 正常状態DBのみ | Status = "normal" のデータベースのみ | データベースフィルタ時 |

### 計算ロジック

- 行分割: `$StoredProcedureText.Split(@("`r`n", "`r", "`n"), [System.StringSplitOptions]::None)`
- 行番号付きマッチ: `Select-String -Pattern $Pattern | ForEach-Object { "(LineNumber: $($_.LineNumber)) $($_.ToString().Trim())" }`

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| プロシージャ定義取得 | sys.sql_modules | SELECT | プロシージャ定義テキスト |
| プロシージャ情報取得 | sys.procedures | SELECT | プロシージャメタデータ |

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

#### sys.sql_modules + sys.procedures

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | m.definition (TextBody) | INNER JOIN sys.procedures p ON m.object_id = p.object_id | プロシージャ定義テキスト |
| SELECT | p.name, OBJECT_SCHEMA_NAME(p.object_id) | - | プロシージャ名とスキーマ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 接続エラー | SQL Serverへの接続失敗 | Stop-Function with -Continue |
| - | バージョンエラー | SQL Server 2005未満 | Warning出力、Continue |

### リトライ仕様

自動リトライは実装されていない。

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

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

## パフォーマンス要件

- プロシージャ数に比例した処理時間
- 大規模データベースでは数千プロシージャを処理する可能性
- IncludeSystemObjects使用時は処理時間が大幅に増加

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

- sys.sql_modules へのアクセス権限が必要
- プロシージャソースコードの読み取りが可能
- 機密情報（接続文字列等）がマッチする可能性あり

## 備考

- 正規表現を使用した高度なパターンマッチングが可能
- 結果にはマッチ行の行番号が含まれる
- StoredProcedure/StoredProcedureFullText はデフォルト非表示（Select-Object * で取得可能）

---

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

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

### 推奨読解順序

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

出力オブジェクトの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Find-DbaStoredProcedure.ps1 | `public/Find-DbaStoredProcedure.ps1` | 174-188行目: 出力PSCustomObject定義 |

**読解のコツ**: Select-DefaultView で StoredProcedure と StoredProcedureFullText が非表示に設定されている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Find-DbaStoredProcedure.ps1 | `public/Find-DbaStoredProcedure.ps1` | 98-110行目: パラメータ定義 |
| 2-2 | Find-DbaStoredProcedure.ps1 | `public/Find-DbaStoredProcedure.ps1` | 112-122行目: beginブロック |

**主要処理フロー**:
1. **113-117行目**: SQLクエリ定義（sys.sql_modules JOIN sys.procedures）
2. **119行目**: IncludeSystemObjects に応じたWHERE句追加

#### Step 3: データベースフィルタリングを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Find-DbaStoredProcedure.ps1 | `public/Find-DbaStoredProcedure.ps1` | 136-148行目: データベースフィルタリング |

**主要処理フロー**:
- **136-139行目**: IncludeSystemDatabases に応じたフィルタ
- **142-147行目**: Database/ExcludeDatabase フィルタ適用

#### Step 4: パターンマッチング処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Find-DbaStoredProcedure.ps1 | `public/Find-DbaStoredProcedure.ps1` | 159-189行目: パターンマッチングと結果生成 |

**主要処理フロー**:
- **166行目**: `-match $Pattern` で正規表現マッチング
- **167行目**: SMO StoredProcedure オブジェクト取得
- **170-172行目**: 行分割とSelect-Stringによる行番号付きマッチ抽出
- **185行目**: StoredProcedureTextFound に行番号付きマッチ行を結合

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

```
Find-DbaStoredProcedure
    │
    ├─ begin ブロック
    │      ├─ SQLクエリ構築
    │      └─ IncludeSystemObjects処理
    │
    ├─ process ブロック
    │      └─ 各SqlInstanceをループ
    │             │
    │             ├─ Connect-DbaInstance
    │             │
    │             ├─ バージョンチェック
    │             │
    │             ├─ データベース一覧取得
    │             │      └─ IncludeSystemDatabases
    │             │      └─ Database/ExcludeDatabase フィルタ
    │             │
    │             └─ 各データベースをループ
    │                    │
    │                    ├─ ExecuteWithResults（SQLクエリ実行）
    │                    │
    │                    └─ 各プロシージャをループ
    │                           │
    │                           ├─ -match $Pattern
    │                           │
    │                           ├─ SMO StoredProcedure取得
    │                           │
    │                           ├─ Split + Select-String
    │                           │      └─ 行番号付きマッチ抽出
    │                           │
    │                           └─ PSCustomObject出力
    │
    └─ end ブロック
           └─ 処理統計出力
```

### データフロー図

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

SqlInstance ────┐
                ├──▶ Connect-DbaInstance
SqlCredential ──┤            │
                │            ▼
Database ───────┤    データベースフィルタリング
                │    (IncludeSystemDatabases,
ExcludeDatabase ┤     Database, ExcludeDatabase)
                │            │
IncludeSysObj ──┤            ▼
                │    各データベースをループ
IncludeSysDB ───┤            │
                │            ▼
Pattern ────────┤    sys.sql_modules + sys.procedures
                │    (ExecuteWithResults)
                │            │
                │            ▼
                │    各プロシージャをループ
                │            │
                │            ▼
                │    TextBody -match $Pattern
                │            │
                │    マッチ時 │
                │            ▼
                │    Split + Select-String
                │    (行番号付きマッチ抽出)
                │            │
                │            ▼
                └────────────────────────────────▶ PSCustomObject
                                                  (マッチしたプロシージャ)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Find-DbaStoredProcedure.ps1 | `public/Find-DbaStoredProcedure.ps1` | ソース | メイン機能実装 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続処理 |
