# 機能設計書 519-Set-DbaAgentSchedule

## 概要

本ドキュメントは、SQL Server Agentジョブスケジュールのプロパティを変更するdbatools関数「Set-DbaAgentSchedule」の機能設計書である。

### 本機能の処理概要

Set-DbaAgentScheduleは、既存のSQL Server Agentジョブスケジュールのタイミング、頻度、有効期間などのプロパティを変更する機能を提供する。

**業務上の目的・背景**：SQL Server Agentジョブはスケジュールに基づいて自動実行される。運用要件の変更、メンテナンスウィンドウの調整、ビジネスアワーの変更などにより、スケジュール設定を更新する必要がある。本機能により、既存スケジュールを再作成することなく、各種プロパティを変更できる。

**機能の利用シーン**：
- スケジュール実行時間の変更
- スケジュール頻度の調整（日次→週次など）
- スケジュールの有効/無効切り替え
- スケジュール名の変更
- サブ日付頻度（毎時、毎分など）の調整
- 有効期間の設定

**主要な処理内容**：
1. 対象SQL Serverインスタンスへの接続
2. 対象ジョブとスケジュールの取得
3. 各種パラメータの検証と変換
4. スケジュールプロパティの更新
5. SMO Alter()メソッドによる変更のコミット
6. 更新後のスケジュール情報の取得と返却

**関連システム・外部連携**：SQL Server JobServer.Jobs、JobSchedules、SharedSchedules

**権限による制御**：sysadmin権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | SQL Server Management Studio - Job Schedule Properties | 参照画面 | スケジュールプロパティの確認・編集 |
| - | PowerShell Console | 主画面 | コマンド実行インターフェース |

## 機能種別

データ更新操作 (UPDATE)

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | Yes | 対象SQL Serverインスタンス | パイプライン入力可 |
| SqlCredential | PSCredential | No | 代替認証資格情報 | - |
| Job | object[] | Yes | 対象ジョブ名 | パイプライン入力可 |
| Schedule | string | Yes | 対象スケジュール名 | エイリアス: ScheduleName |
| NewName | string | No | 新しいスケジュール名 | - |
| Enabled | switch | No | スケジュールを有効化 | - |
| Disabled | switch | No | スケジュールを無効化 | - |
| FrequencyType | object | No | 頻度タイプ | Once, Daily, Weekly, Monthly, MonthlyRelative, AgentStart, OnIdle |
| FrequencyInterval | object[] | No | 頻度間隔 | 日/曜日/日付 |
| FrequencySubdayType | object | No | サブ日付頻度タイプ | Once, Seconds, Minutes, Hours |
| FrequencySubdayInterval | int | No | サブ日付頻度間隔 | - |
| FrequencyRelativeInterval | object | No | 相対頻度間隔 | First, Second, Third, Fourth, Last |
| FrequencyRecurrenceFactor | int | No | 再発係数 | - |
| StartDate | string | No | 開始日 | yyyyMMdd形式 |
| EndDate | string | No | 終了日 | yyyyMMdd形式 |
| StartTime | string | No | 開始時刻 | HHMMSS形式 |
| EndTime | string | No | 終了時刻 | HHMMSS形式 |
| EnableException | switch | No | 例外処理を有効化 | - |
| Force | switch | No | 検証エラーをスキップ | - |

### 入力データソース

- SQL Server JobServer.Jobs[$j].JobSchedulesコレクション

## 出力仕様

### 出力データ

Get-DbaAgentScheduleからのスケジュールオブジェクト

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverのコンピュータ名 |
| InstanceName | string | インスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| Name | string | スケジュール名 |
| Enabled/IsEnabled | bool | 有効状態 |
| FrequencyTypes | string | 頻度タイプ |
| FrequencyInterval | int | 頻度間隔 |
| FrequencySubDayTypes | string | サブ日付頻度タイプ |
| FrequencySubDayInterval | int | サブ日付頻度間隔 |
| ActiveStartDate | DateTime | 有効開始日 |
| ActiveEndDate | DateTime | 有効終了日 |
| ActiveStartTimeOfDay | TimeSpan | 日次開始時刻 |
| ActiveEndTimeOfDay | TimeSpan | 日次終了時刻 |

### 出力先

PowerShellパイプライン（Get-DbaAgentScheduleの出力）

## 処理フロー

### 処理シーケンス

```
1. 初期設定（beginブロック）
   ├─ Forceフラグによる確認プロンプト制御
   ├─ FrequencyTypeの文字列→整数変換
   ├─ FrequencySubdayTypeの文字列→整数変換
   ├─ FrequencyIntervalのビットマスク計算
   ├─ FrequencyRelativeIntervalの文字列→整数変換
   └─ 日付/時刻の検証とフォーマット変換

2. 各インスタンスの処理（processブロック）
   ├─ Connect-DbaInstanceで接続
   └─ 各ジョブをループ
       ├─ ジョブ存在確認
       ├─ スケジュール存在確認
       └─ スケジュールプロパティの更新
           ├─ NewName → Rename()
           ├─ Enabled/Disabled → IsEnabled
           ├─ FrequencyTypes
           ├─ FrequencyInterval
           ├─ FrequencySubDayTypes
           ├─ FrequencySubDayInterval
           ├─ FrequencyRelativeIntervals
           ├─ FrequencyRecurrenceFactor
           ├─ ActiveStartDate/ActiveEndDate
           └─ ActiveStartTimeOfDay/ActiveEndTimeOfDay

3. 変更のコミット
   ├─ ShouldProcess確認
   ├─ Alter()メソッド呼び出し
   ├─ SharedSchedules.Refresh()
   └─ Get-DbaAgentScheduleで結果取得

4. 完了処理（endブロック）
   └─ 完了メッセージ出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[beginブロック: パラメータ変換と検証]
    B --> C[FrequencyType→整数変換]
    C --> D[FrequencySubdayType→整数変換]
    D --> E[FrequencyInterval計算]
    E --> F[FrequencyRelativeInterval→整数変換]
    F --> G[日付/時刻検証]
    G --> H{検証OK?}
    H -->|No| I[エラー: パラメータ不正]
    H -->|Yes| J[日付/時刻フォーマット変換]
    J --> K[processブロック]
    K --> L[各インスタンスをループ]
    L --> M[Connect-DbaInstance]
    M --> N[各ジョブをループ]
    N --> O{ジョブ存在?}
    O -->|No| P[警告: ジョブ不存在]
    O -->|Yes| Q{スケジュール存在?}
    Q -->|No| R[エラー: スケジュール不存在]
    Q -->|Yes| S[スケジュールオブジェクト取得]
    S --> T{FrequencyInterval = 0?}
    T -->|Yes| U[Interval = 1に設定]
    T -->|No| V[プロパティ更新]
    U --> V
    V --> W[ShouldProcess確認]
    W --> X[Alter実行]
    X --> Y[SharedSchedules.Refresh]
    Y --> Z[Get-DbaAgentSchedule]
    Z --> AA{次のジョブ?}
    AA -->|Yes| N
    AA -->|No| AB{次のインスタンス?}
    AB -->|Yes| L
    AB -->|No| AC[endブロック: 完了メッセージ]
    AC --> AD[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 日次頻度間隔範囲 | FrequencyType=Dailyの場合、FrequencyIntervalは1-365または'EveryDay' | FrequencyType=Daily |
| BR-002 | 再発係数必須 | 週次/月次の場合、FrequencyRecurrenceFactor >= 1 | FrequencyType in (Weekly, Monthly) |
| BR-003 | サブ日付間隔範囲 | Seconds/Minutesは1-59、Hoursは1-23 | FrequencySubdayType指定時 |
| BR-004 | 日付フォーマット | 日付はyyyyMMdd形式 | StartDate/EndDate指定時 |
| BR-005 | 終了日制約 | EndDateはStartDateより後 | EndDate指定時 |
| BR-006 | 時刻フォーマット | 時刻はHHMMSS形式（000000-235959） | StartTime/EndTime指定時 |
| BR-007 | デフォルトInterval | 新規スケジュールでFrequencyInterval=0の場合、1に設定 | FrequencyInterval=0 |

### 計算ロジック

**FrequencyTypeの変換**：
- Once/OneTime → 1
- Daily → 4
- Weekly → 8
- Monthly → 16
- MonthlyRelative → 32
- AgentStart/AutoStart → 64
- IdleComputer/OnIdle → 128

**FrequencyIntervalの計算（Weekly）**：
- Sunday = 1, Monday = 2, Tuesday = 4, Wednesday = 8
- Thursday = 16, Friday = 32, Saturday = 64
- Weekdays = 62, Weekend = 65, EveryDay = 127

**FrequencyRelativeIntervalの変換**：
- First = 1, Second = 2, Third = 4, Fourth = 8, Last = 16

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| スケジュール更新 | msdb.dbo.sysschedules | UPDATE | スケジュールプロパティの更新 |

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

#### msdb.dbo.sysschedules

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | name | NewName指定値 | Rename()経由 |
| UPDATE | enabled | Enabled/Disabled | - |
| UPDATE | freq_type | FrequencyType | - |
| UPDATE | freq_interval | FrequencyInterval | - |
| UPDATE | freq_subday_type | FrequencySubdayType | - |
| UPDATE | freq_subday_interval | FrequencySubdayInterval | - |
| UPDATE | freq_relative_interval | FrequencyRelativeInterval | - |
| UPDATE | freq_recurrence_factor | FrequencyRecurrenceFactor | - |
| UPDATE | active_start_date | StartDate | - |
| UPDATE | active_end_date | EndDate | - |
| UPDATE | active_start_time | StartTime | - |
| UPDATE | active_end_time | EndTime | - |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Stop-Function | FrequencyInterval範囲外（Daily） | 1-365を指定 |
| - | Stop-Function | FrequencyRecurrenceFactor < 1（Weekly/Monthly） | 1以上を指定、または-Force使用 |
| - | Stop-Function | FrequencySubdayInterval範囲外 | 適切な範囲を指定 |
| - | Stop-Function | 日付フォーマット不正 | yyyyMMdd形式で指定 |
| - | Stop-Function | EndDate < StartDate | 正しい日付範囲を指定 |
| - | Stop-Function | 時刻フォーマット不正 | HHMMSS形式で指定 |
| - | Warning | ジョブが存在しない | ジョブ名を確認 |
| - | Stop-Function | スケジュールが存在しない | スケジュール名を確認 |
| - | Stop-Function | スケジュール変更失敗 | エラーメッセージを確認 |

### リトライ仕様

リトライ機能なし。エラー発生時は-Continueにより次の処理を継続。

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

SMOのAlter()メソッドによる暗黙的トランザクション。

## パフォーマンス要件

特に定義なし。

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

- sysadmin権限が必要
- WhatIf/Confirmパラメータによる事前確認が可能

## 備考

- SQL Server 2000以上に対応
- 同一名のスケジュールが複数ある場合、最初のものが選択される
- 複数サーバー・複数ジョブの一括変更に対応

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Microsoft.SqlServer.Management.Smo.Agent.JobSchedule | SMO | スケジュールオブジェクトのプロパティ |

**読解のコツ**: JobScheduleにはFrequencyTypes、FrequencyInterval、ActiveStartDate、ActiveStartTimeOfDayなど多くのプロパティがある。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Set-DbaAgentSchedule.ps1 | `public/Set-DbaAgentSchedule.ps1` | 関数定義、パラメータ、ブロック構造 |

**主要処理フロー**:
1. **170-200行目**: CmdletBinding属性とパラメータ定義
2. **202-410行目**: beginブロック - パラメータ変換と検証
3. **412-532行目**: processブロック - メイン処理
4. **534-537行目**: endブロック - 完了メッセージ

#### Step 3: パラメータ変換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Set-DbaAgentSchedule.ps1 | `public/Set-DbaAgentSchedule.ps1` | beginブロックの変換ロジック |

**主要処理フロー**:
- **206-221行目**: FrequencyType→整数変換
- **223-237行目**: FrequencySubdayType→整数変換
- **266-350行目**: FrequencyInterval計算（曜日、月日など）
- **352-364行目**: FrequencyRelativeInterval→整数変換
- **366-410行目**: 日付/時刻検証とフォーマット変換

#### Step 4: スケジュール更新処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Set-DbaAgentSchedule.ps1 | `public/Set-DbaAgentSchedule.ps1` | processブロックの更新ロジック |

**主要処理フロー**:
- **434行目**: 複数スケジュール対応（最初を選択）
- **436-439行目**: FrequencyInterval=0の場合のデフォルト設定
- **441-508行目**: 各プロパティの更新
- **510-526行目**: Alter実行と結果取得

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

```
Set-DbaAgentSchedule
    │
    ├─ Connect-DbaInstance
    │
    ├─ JobServer.Jobs[$j] (ジョブ取得)
    │
    ├─ Job.JobSchedules[$Schedule] (スケジュール取得)
    │
    ├─ JobSchedule.Rename() (名前変更時)
    │
    ├─ JobSchedule.Alter() (変更コミット)
    │
    ├─ SharedSchedules.Refresh() (キャッシュ更新)
    │
    └─ Get-DbaAgentSchedule (結果取得)
```

### データフロー図

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

SqlInstance ─────────▶ Connect-DbaInstance
      │                        │
Job名 ──────────────▶ ジョブ取得
      │                        │
Schedule名 ──────────▶ スケジュール取得
      │                        │
FrequencyType ────────▶ 整数変換
      │                        │
FrequencyInterval ───▶ ビットマスク計算
      │                        │
日付/時刻パラメータ ──▶ 検証 + フォーマット変換
      │                        │
      ▼                        ▼
                       プロパティ更新
                       ├─ IsEnabled
                       ├─ FrequencyTypes
                       ├─ FrequencyInterval
                       ├─ FrequencySubDayTypes
                       ├─ FrequencySubDayInterval
                       ├─ FrequencyRelativeIntervals
                       ├─ FrequencyRecurrenceFactor
                       ├─ ActiveStartDate/EndDate
                       └─ ActiveStartTimeOfDay/EndTimeOfDay
                              │
                              ▼
                         Alter()
                              │
                              ▼
                   Get-DbaAgentSchedule ───▶ [Schedule出力]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Set-DbaAgentSchedule.ps1 | `public/Set-DbaAgentSchedule.ps1` | ソース | メイン関数 |
| Get-DbaAgentSchedule.ps1 | `public/Get-DbaAgentSchedule.ps1` | ソース | スケジュール取得 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続 |
