# 機能設計書 256-Update-DbaMaintenanceSolution

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおける`Update-DbaMaintenanceSolution`コマンドレットの機能設計書です。既存のOla Hallengrenメンテナンスソリューションのストアドプロシージャを最新バージョンに更新します。

### 本機能の処理概要

`Update-DbaMaintenanceSolution`コマンドは、SQL Serverインスタンスにインストールされている Ola Hallengren のメンテナンスソリューションのストアドプロシージャを、GitHubから最新版をダウンロードして更新します。既存のテーブル、ジョブ、構成はそのまま保持されます。

**業務上の目的・背景**：Ola Hallengrenのメンテナンスソリューションは、SQL Serverのバックアップ、インデックス最適化、整合性チェックを自動化する広く使われているオープンソースツールです。バグ修正や改善を取り込むために、ストアドプロシージャを最新版に更新する必要がありますが、既存のジョブやテーブルを壊さずに更新することが重要です。本機能は、ストアドプロシージャのみを安全に更新し、既存環境を維持したままバグ修正や改善を適用できるようにします。

**機能の利用シーン**：
- Ola Hallengrenメンテナンスソリューションのセキュリティ修正適用
- 機能改善やバグ修正の取り込み
- 複数サーバーの一括更新
- オフライン環境での更新（LocalFileパラメータ使用）

**主要な処理内容**：
1. GitHubから最新のメンテナンスソリューションをダウンロード（またはローカルファイル使用）
2. 対象インスタンスに既存のストアドプロシージャが存在するか確認
3. 存在するストアドプロシージャのみを更新
4. 更新結果をレポート

**関連システム・外部連携**：
- GitHub（https://ola.hallengren.com）からのファイルダウンロード
- SQL Serverのメンテナンスソリューションストアドプロシージャ

**権限による制御**：対象データベースでのストアドプロシージャCREATE/ALTER権限が必要です。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はPowerShellコマンドレットであり、関連するGUI画面はありません |

## 機能種別

更新処理 / メンテナンス

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstance[] | Yes | 更新対象のSQL Serverインスタンス | パイプライン入力可能 |
| SqlCredential | PSCredential | No | 代替認証情報 | - |
| Database | string | No | メンテナンスソリューションのデータベース | デフォルト "master" |
| Solution | string[] | No | 更新対象コンポーネント | ValidateSet: All, Backup, IntegrityCheck, IndexOptimize, CommandExecute |
| LocalFile | string | No | ローカルのzipファイルパス | インターネット不可環境用 |
| Force | switch | No | キャッシュ無視で強制ダウンロード | - |
| WhatIf | switch | No | 実行内容のプレビュー | SupportsShouldProcess |
| Confirm | switch | No | 実行前確認 | SupportsShouldProcess |
| EnableException | switch | No | 例外を有効にする | - |

### 入力データソース

- コマンドラインからの直接入力
- パイプライン経由での入力
- ローカルzipファイル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverインスタンスのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| Solution | string | 更新されたソリューションコンポーネント名 |
| Procedure | string | 更新されたストアドプロシージャ名 |
| IsUpdated | bool | 更新成功の場合$true |
| Results | string/object | 更新結果またはエラーメッセージ |

### Results値

| 値 | 説明 |
|---|-----|
| "Updated" | 正常に更新完了 |
| "Procedure not installed" | ストアドプロシージャが未インストール |
| "File not found" | SQLファイルが見つからない |
| （エラーオブジェクト） | 更新失敗時のエラー |

### 出力先

- PowerShellパイプライン（PSCustomObject）

## 処理フロー

### 処理シーケンス

```
1. begin ブロック
   ├─ Solutionが'All'の場合、全コンポーネントに展開
   ├─ CommandExecuteを最初に配置（依存関係のため）
   └─ キャッシュ確認とダウンロード
       ├─ Force指定またはキャッシュなしの場合
       └─ Save-DbaCommunitySoftwareでダウンロード
2. process ブロック
   └─ 各SqlInstanceに対してループ処理
       ├─ Connect-DbaInstance（NonPooledConnection）
       ├─ データベース存在確認
       ├─ Get-DbaModuleでインストール済みプロシージャ確認
       └─ 各Solutionに対してループ処理
           ├─ プロシージャ名の決定
           │   ├─ Backup → DatabaseBackup
           │   ├─ IntegrityCheck → DatabaseIntegrityCheck
           │   └─ その他 → そのまま
           ├─ インストール済み確認
           │   └─ 未インストールの場合はスキップ
           ├─ SQLファイル検索
           │   └─ 見つからない場合はスキップ
           ├─ Invoke-DbaQueryでSQLファイル実行
           └─ 結果出力
       └─ Disconnect-DbaInstance（NonPooled接続のクローズ）
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{Solution == All?}
    B -->|Yes| C[全コンポーネント展開]
    B -->|No| D[CommandExecuteを先頭に]
    C --> D
    D --> E{キャッシュ存在 & !Force?}
    E -->|No| F[Save-DbaCommunitySoftware]
    E -->|Yes| G[キャッシュ使用]
    F --> G
    G --> H{SqlInstanceループ}
    H -->|次| I[Connect-DbaInstance]
    I --> J{データベース存在?}
    J -->|No| K[Stop-Function/Continue]
    J -->|Yes| L[Get-DbaModule]
    L --> M{Solutionループ}
    M -->|次| N[プロシージャ名決定]
    N --> O{インストール済み?}
    O -->|No| P[Results='Not installed']
    O -->|Yes| Q{SQLファイル存在?}
    Q -->|No| R[Results='File not found']
    Q -->|Yes| S[Invoke-DbaQuery]
    S -->|成功| T[Results='Updated']
    S -->|失敗| U[Results=エラー]
    P --> V[出力]
    R --> V
    T --> V
    U --> V
    V --> M
    M -->|完了| W[Disconnect-DbaInstance]
    W --> H
    H -->|完了| X[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | CommandExecute優先 | CommandExecuteは他のプロシージャの依存先のため最初に更新 | Solution配列にCommandExecuteが含まれる場合 |
| BR-002 | 既存プロシージャのみ | 未インストールのプロシージャは更新しない | 常に適用 |
| BR-003 | NonPooled接続 | 接続プールを使用しない専用接続 | 常に適用 |

### プロシージャ名マッピング

| Solution値 | プロシージャ名 |
|-----------|--------------|
| CommandExecute | CommandExecute |
| Backup | DatabaseBackup |
| IntegrityCheck | DatabaseIntegrityCheck |
| IndexOptimize | IndexOptimize |

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

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

| 操作 | 対象 | 操作種別 | 概要 |
|-----|-----|---------|------|
| プロシージャ確認 | sys.sql_modules | SELECT | Get-DbaModule経由 |
| プロシージャ更新 | ストアドプロシージャ | CREATE OR ALTER | SQLファイル実行 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ConnectionError | 接続エラー | SQL Server接続失敗 | Stop-FunctionでContinue |
| DatabaseNotFound | データベース不在 | 指定データベースが存在しない | Stop-FunctionでContinue |
| DownloadError | ダウンロードエラー | GitHubからのダウンロード失敗 | Stop-Functionで終了 |

### リトライ仕様

本機能にはリトライ機能はありません。

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

ストアドプロシージャの更新は各プロシージャごとに個別に実行されます。1つのプロシージャ更新失敗が他のプロシージャに影響することはありません。

## パフォーマンス要件

- GitHubからのダウンロードはネットワーク速度に依存
- 各プロシージャの更新は通常数秒で完了
- NonPooled接続を使用するため、処理完了後に明示的に切断

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

- ストアドプロシージャのCREATE/ALTER権限が必要
- 信頼できるソース（GitHub公式リポジトリ）からのダウンロード
- LocalFileパラメータで検証済みファイルの使用も可能

## 備考

- Install-DbaMaintenanceSolutionの軽量版として機能
- テーブルやジョブの再作成は行わない
- スキーマ変更を伴う更新の場合はInstall-DbaMaintenanceSolutionが必要

---

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

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

### 推奨読解順序

#### Step 1: パラメータと初期化を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Update-DbaMaintenanceSolution.ps1 | `public/Update-DbaMaintenanceSolution.ps1` | 83-95行目：パラメータ定義 |

**主要処理フロー**:
1. **89行目**: Databaseのデフォルト値 "master"
2. **90-91行目**: Solutionの ValidateSet とデフォルト 'All'

#### Step 2: beginブロックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Update-DbaMaintenanceSolution.ps1 | `public/Update-DbaMaintenanceSolution.ps1` | 96-118行目：初期化とダウンロード |

**主要処理フロー**:
- **99-104行目**: Solution展開とCommandExecute優先配置
- **107-108行目**: キャッシュパス設定
- **109-117行目**: 必要に応じてダウンロード実行

#### Step 3: processブロックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Update-DbaMaintenanceSolution.ps1 | `public/Update-DbaMaintenanceSolution.ps1` | 120-182行目：更新処理 |

**主要処理フロー**:
- **127行目**: Connect-DbaInstance -NonPooledConnection
- **137行目**: Get-DbaModuleでインストール済みプロシージャ確認
- **140-144行目**: プロシージャ名のマッピング
- **166行目**: Invoke-DbaQueryでSQLファイル実行
- **180行目**: Disconnect-DbaInstance

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

```
Update-DbaMaintenanceSolution
    │
    ├─ Save-DbaCommunitySoftware
    │      └─ GitHubからダウンロード
    │
    ├─ Connect-DbaInstance -NonPooledConnection
    │
    ├─ Get-DbaModule
    │      └─ インストール済みプロシージャ確認
    │
    ├─ Get-ChildItem
    │      └─ SQLファイル検索
    │
    ├─ Invoke-DbaQuery -File
    │      └─ SQLファイル実行
    │
    └─ Disconnect-DbaInstance
```

### データフロー図

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

GitHubまたは       ───▶ Save-DbaCommunitySoftware
LocalFile                   │
                            ▼
                     ローカルキャッシュ
                            │
SqlInstance        ───▶ Connect-DbaInstance
                            │
Database           ───────┘
                            │
                            ▼
                     Get-DbaModule ───▶ インストール済み確認
                            │
Solution           ───▶ 対象プロシージャ決定
                            │
                            ▼
                     Invoke-DbaQuery ───▶ PSCustomObject出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Update-DbaMaintenanceSolution.ps1 | `public/Update-DbaMaintenanceSolution.ps1` | ソース | メイン関数定義 |
| Install-DbaMaintenanceSolution.ps1 | `public/Install-DbaMaintenanceSolution.ps1` | ソース | 完全インストール関数 |
| Save-DbaCommunitySoftware.ps1 | `public/Save-DbaCommunitySoftware.ps1` | ソース | GitHubダウンロード関数 |
| Get-DbaModule.ps1 | `public/Get-DbaModule.ps1` | ソース | モジュール取得関数 |
| Invoke-DbaQuery.ps1 | `public/Invoke-DbaQuery.ps1` | ソース | クエリ実行関数 |
