# 機能設計書 657-Copy-DbaStartupProcedure

## 概要

本ドキュメントは、dbatools PowerShellモジュールの `Copy-DbaStartupProcedure` 関数の機能設計を記述するものである。本機能はmasterデータベースのスタートアッププロシージャをSQL Serverインスタンス間でコピーするコマンドレットである。

### 本機能の処理概要

**業務上の目的・背景**：
スタートアッププロシージャは、SQL Serverサービス起動時に自動的に実行されるストアドプロシージャである。サーバー初期化タスク、カスタム監視のセットアップ、構成検証などに使用される。本機能は、これらのスタートアッププロシージャをソースサーバーから宛先サーバーのmasterデータベースにコピーし、スタートアップ設定を適用することで、サーバー移行やディザスタリカバリ環境の構築を支援する。

**機能の利用シーン**：
- SQL Server移行時のスタートアッププロシージャ移行
- ディザスタリカバリ環境の構築
- 複数サーバーでのスタートアップ構成標準化
- 開発環境から本番環境へのプロシージャ展開

**主要な処理内容**：
1. ソースサーバーへの接続とスタートアッププロシージャの列挙
2. 各宛先サーバーへの接続と既存プロシージャの確認
3. プロシージャ定義のコピー（TextHeader + TextBody）
4. sp_procoption によるスタートアップ設定の適用
5. 処理結果の出力

**関連システム・外部連携**：
- Get-DbaModule コマンドレットによるスタートアッププロシージャ検出
- SQL Server SMO（StoredProcedures オブジェクト）
- Invoke-DbaQuery によるプロシージャ作成
- sp_procoption システムプロシージャ

**権限による制御**：
- masterデータベースへの書き込み権限が必要
- sp_procoption 実行には sysadmin 権限が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLI (PowerShell) | 主画面 | コマンドライン実行によるプロシージャコピー |

## 機能種別

データ移行処理（INSERT/UPDATE/DELETE）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Source | DbaInstanceParameter | Yes | ソースSQL Serverインスタンス | 必須 |
| SourceSqlCredential | PSCredential | No | ソース接続用資格情報 | - |
| Destination | DbaInstanceParameter[] | Yes | 宛先SQL Serverインスタンス（複数可） | 必須 |
| DestinationSqlCredential | PSCredential | No | 宛先接続用資格情報 | - |
| Procedure | string[] | No | コピー対象のプロシージャ名 | - |
| ExcludeProcedure | string[] | No | 除外するプロシージャ名 | - |
| Force | switch | No | 既存プロシージャの上書き | - |
| EnableException | switch | No | 例外処理の有効化 | - |

### 入力データソース

- PowerShellコマンドラインからのパラメータ入力
- Get-DbaModule によるスタートアッププロシージャ情報
- SMO StoredProcedures オブジェクトからのプロシージャ定義

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| DateTime | DbaDateTime | 処理日時 |
| SourceServer | string | ソースサーバー名 |
| DestinationServer | string | 宛先サーバー名 |
| Name | string | プロシージャ名 |
| Schema | string | スキーマ名 |
| Type | string | オブジェクトタイプ（常に"Startup Stored Procedure"） |
| Status | string | 処理結果（Successful/Skipped/Failed） |
| Notes | string | 補足情報 |

### 出力先

PowerShellパイプライン（MigrationObject型として出力）

## 処理フロー

### 処理シーケンス

```
1. 初期化処理（beginブロック）
   └─ ソースサーバーへの接続
   └─ Get-DbaModule でスタートアッププロシージャ取得
   └─ Forceオプション確認

2. メイン処理（processブロック）
   └─ 各宛先サーバーに対して処理
       └─ 宛先サーバーへの接続
       └─ 宛先のプロシージャ一覧取得
       └─ 各スタートアッププロシージャの処理
           └─ フィルタ適用（include/exclude）
           └─ 既存チェック
           └─ Forceの場合は既存削除
           └─ プロシージャ定義のコピー（TextHeader + TextBody）
           └─ sp_procoption によるスタートアップ設定
           └─ 結果出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[ソースサーバー接続]
    B --> C{接続成功?}
    C -->|No| D[エラー終了]
    C -->|Yes| E[Get-DbaModule ExecIsStartup]
    E --> F[各宛先サーバーをループ]
    F --> G[宛先サーバー接続]
    G --> H{接続成功?}
    H -->|No| I[スキップして次へ]
    H -->|Yes| J[宛先プロシージャ一覧取得]
    J --> K[各スタートアッププロシージャをループ]
    K --> L{include/excludeフィルタ?}
    L -->|除外| M[次のプロシージャへ]
    L -->|対象| N{宛先に存在?}
    N -->|No| O[プロシージャ作成]
    N -->|Yes| P{Force?}
    P -->|No| Q[Skipped出力]
    P -->|Yes| R[既存プロシージャ削除]
    R --> O
    O --> S[TextHeader + TextBody取得]
    S --> T[Invoke-DbaQuery実行]
    T --> U[sp_procoption STARTUP ON]
    U --> V{成功?}
    V -->|Yes| W[Successful出力]
    V -->|No| X[Failed出力]
    W --> Y{次のプロシージャ?}
    X --> Y
    Q --> Y
    Y -->|Yes| K
    Y -->|No| Z{次の宛先?}
    Z -->|Yes| F
    Z -->|No| AA[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | ExecIsStartupフィルタ | ExecIsStartup = true のプロシージャのみ対象 | プロシージャ列挙時 |
| BR-002 | masterデータベース限定 | スタートアッププロシージャはmasterデータベースのみ | 常時 |
| BR-003 | 既存スキップ | Force未指定時は既存プロシージャをスキップ | 宛先チェック時 |
| BR-004 | 最小バージョン要件 | SQL Server 2005以上 | インスタンス接続時 |

### 計算ロジック

- プロシージャSQL = TextHeader + TextBody

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| プロシージャ列挙 | sys.sql_modules + sys.procedures | SELECT | Get-DbaModule経由 |
| プロシージャ削除 | master.sys.procedures | DELETE | DROP PROCEDURE |
| プロシージャ作成 | master.sys.procedures | INSERT | CREATE PROCEDURE |
| スタートアップ設定 | - | UPDATE（間接） | sp_procoption実行 |

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

#### master.sys.procedures（間接）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | - | DROP PROCEDURE [{schema}].[{name}] | Force時 |
| INSERT | - | CREATE PROCEDURE（TextHeader + TextBody） | プロシージャ作成 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 接続エラー | ソース/宛先サーバーへの接続失敗 | Stop-Function |
| - | 削除エラー | 既存プロシージャの削除失敗 | Failed出力、次のプロシージャへ |
| - | 作成エラー | プロシージャ作成/sp_procoption失敗 | Failed出力、次のプロシージャへ |

### リトライ仕様

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

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

- 各プロシージャの操作は個別に実行される
- ロールバック機能は提供されない

## パフォーマンス要件

- プロシージャの数に比例した処理時間
- ネットワーク状態に依存

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

- sysadmin権限が必要（sp_procoption実行のため）
- masterデータベースへの書き込み権限が必要
- SqlCredentialパラメータによるセキュアな資格情報の受け渡し

## 備考

- Get-DbaModule を使用してスタートアッププロシージャを特定
- SMOのTextHeader/TextBodyを連結してプロシージャ定義を再構築
- Invoke-DbaQueryでプロシージャを作成し、別途sp_procoptionでスタートアップ設定を適用

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Copy-DbaStartupProcedure.ps1 | `public/Copy-DbaStartupProcedure.ps1` | 142-151行目: $copyStartupProcStatus オブジェクト定義 |

**読解のコツ**: MigrationObject型として出力され、DateTime, SourceServer, DestinationServer, Name, Type, Status, Notes がデフォルト表示される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Copy-DbaStartupProcedure.ps1 | `public/Copy-DbaStartupProcedure.ps1` | 100-112行目: パラメータ定義 |
| 2-2 | Copy-DbaStartupProcedure.ps1 | `public/Copy-DbaStartupProcedure.ps1` | 114-125行目: beginブロック |

**主要処理フロー**:
1. **115-120行目**: ソースサーバー接続
2. **122行目**: Get-DbaModule でスタートアッププロシージャ取得
3. **124行目**: Forceオプション確認

#### Step 3: プロシージャコピー処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Copy-DbaStartupProcedure.ps1 | `public/Copy-DbaStartupProcedure.ps1` | 187-199行目: プロシージャ定義取得と作成 |

**主要処理フロー**:
- **190行目**: StoredProcedures.Item でSMOオブジェクト取得
- **191-193行目**: TextHeader + TextBody でSQL生成
- **195行目**: Invoke-DbaQuery でプロシージャ作成
- **196-198行目**: sp_procoption でスタートアップ設定

#### Step 4: 既存チェックと削除処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Copy-DbaStartupProcedure.ps1 | `public/Copy-DbaStartupProcedure.ps1` | 161-184行目: 既存チェックと削除 |

**主要処理フロー**:
- **161行目**: $destStartupProcs.Name -contains で存在確認
- **175行目**: DROP PROCEDURE でプロシージャ削除

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

```
Copy-DbaStartupProcedure
    │
    ├─ begin ブロック
    │      ├─ Connect-DbaInstance（ソース）
    │      └─ Get-DbaModule -Type StoredProcedure -Database master
    │             └─ Where-Object ExecIsStartup
    │
    └─ process ブロック
           └─ 各宛先サーバーをループ
                  │
                  ├─ Connect-DbaInstance（宛先）
                  │
                  ├─ Get-DbaModule（宛先のプロシージャ一覧）
                  │
                  └─ 各スタートアッププロシージャをループ
                         │
                         ├─ フィルタ適用
                         │
                         ├─ 既存チェック
                         │      └─ Force時: DROP PROCEDURE
                         │
                         ├─ StoredProcedures.Item
                         │      └─ TextHeader + TextBody
                         │
                         ├─ Invoke-DbaQuery（プロシージャ作成）
                         │
                         └─ sp_procoption STARTUP ON
```

### データフロー図

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

Source ─────────┐
                ├──▶ Connect-DbaInstance（ソース）
SourceSqlCred ──┤            │
                │            ▼
                │    Get-DbaModule
                │    (ExecIsStartup = true)
                │            │
Destination ────┤            ▼
                ├──▶ 各宛先サーバーをループ
DestinationSql ─┤            │
                │            ▼
Procedure ──────┤    フィルタ適用 + 既存チェック
                │            │
ExcludeProcedure┤            ▼
                │    ┌───────┴───────┐
Force ──────────┤    │ Force?      │
                │    └───────┬───────┘
                │    Yes│         │No
                │       ▼         │
                │    DROP PROC    │
                │       │         │
                │       ▼         ▼
                │    TextHeader + TextBody
                │       │
                │       ▼
                │    Invoke-DbaQuery
                │       │
                │       ▼
                │    sp_procoption STARTUP ON
                │       │
                │       ▼
                └────────────────────────────────▶ MigrationObject
                                                  (Successful/Skipped/Failed)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Copy-DbaStartupProcedure.ps1 | `public/Copy-DbaStartupProcedure.ps1` | ソース | メイン機能実装 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続処理 |
| Get-DbaModule.ps1 | `public/Get-DbaModule.ps1` | ソース | モジュール情報取得 |
| Invoke-DbaQuery.ps1 | `public/Invoke-DbaQuery.ps1` | ソース | SQLクエリ実行 |
