# 機能設計書 574-Remove-DbaDbRole

## 概要

本ドキュメントは、SQL Serverデータベースからカスタムデータベースロールを削除する `Remove-DbaDbRole` 機能の設計仕様を定義するものです。

### 本機能の処理概要

`Remove-DbaDbRole` は、SQL Serverデータベースからユーザー定義のデータベースロールを削除するdbatools PowerShellコマンドレットです。固定データベースロール（db_owner、db_datareaderなど）やpublicロールは保護され、誤って削除されることを防ぎます。スキーマ所有権の処理も自動的に行い、依存関係の問題を解決しながらロールを安全に削除します。

**業務上の目的・背景**：アプリケーションのライフサイクルやセキュリティモデルの変更に伴い、不要になったカスタムデータベースロールを適切に削除する必要があります。手動でのロール削除は、スキーマ所有権などの依存関係によりエラーになりやすく、本機能はこれらを自動的に処理します。

**機能の利用シーン**：
- アプリケーション廃止時のセキュリティオブジェクトクリーンアップ
- セキュリティモデルの再構築時の旧ロール削除
- 開発/テスト環境のリセット
- セキュリティ監査後の不要ロール削除

**主要な処理内容**：
1. 入力オブジェクトタイプの判定（インスタンス、データベース、ロール）
2. Get-DbaDbRoleによる対象ロールの取得（固定ロール除外）
3. システムデータベース除外（IncludeSystemDbs未指定時）
4. スキーマ所有権の確認と処理
5. SMOのDrop()メソッドによるロール削除

**関連システム・外部連携**：SQL Server SMOライブラリ、Get-DbaDbRoleとの連携。

**権限による制御**：ALTER ANY ROLE権限または同等の権限が必要。スキーマ所有権の変更にはALTER SCHEMA権限も必要です。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | SSMSデータベースロール管理画面 | 参照画面 | GUIでのロール削除に相当する操作 |

## 機能種別

CRUD操作（Delete）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstance[] | No* | 対象のSQL Serverインスタンス | 有効なインスタンス名 |
| SqlCredential | PSCredential | No | 代替認証情報 | 有効なPSCredentialオブジェクト |
| Database | String[] | No | 対象データベース | ワイルドカード対応 |
| ExcludeDatabase | String[] | No | 除外データベース | ワイルドカード対応 |
| Role | String[] | No | 削除対象ロール | ワイルドカード対応 |
| ExcludeRole | String[] | No | 除外ロール | ワイルドカード対応 |
| IncludeSystemDbs | Switch | No | システムDBを含めるフラグ | - |
| InputObject | Object[] | No* | パイプライン入力 | サーバー/DB/ロールオブジェクト |
| Force | Switch | No | 強制削除フラグ | - |
| EnableException | Switch | No | 例外を有効化するスイッチ | - |

*SqlInstanceまたはInputObjectのいずれかが必須

### 入力データソース

- PowerShellコマンドライン入力
- パイプライン入力（サーバー、データベース、ロールオブジェクト）

## 出力仕様

### 出力データ

本機能は出力オブジェクトを返しません。処理結果はVerboseメッセージおよびWarningメッセージで通知されます。

### 出力先

- コンソール（Write-Message経由）

## 処理フロー

### 処理シーケンス

```
1. 入力検証
   └─ InputObjectまたはSqlInstanceの指定を確認
2. 入力オブジェクトタイプ判定
   ├─ DbaInstanceParameter → Get-DbaDbRoleで取得
   ├─ Server → Get-DbaDbRoleで取得
   ├─ Database → Get-DbaDbRoleで取得
   └─ DatabaseRole → 直接使用
3. ロールループ
   ├─ システムDBチェック
   ├─ 固定ロール・publicロールチェック
   ├─ ShouldProcess確認
   ├─ スキーマ所有権確認と処理
   └─ Drop()実行
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{InputObject or SqlInstance指定?}
    B -->|No| C[エラー: 入力必須]
    B -->|Yes| D[入力タイプ判定]
    D --> E{タイプ?}
    E -->|DbaInstanceParameter| F[Get-DbaDbRole呼び出し]
    E -->|Server| F
    E -->|Database| G[パイプ経由Get-DbaDbRole]
    E -->|DatabaseRole| H[直接使用]
    E -->|その他| I[エラー: 無効な入力]
    F --> J[ロールループ開始]
    G --> J
    H --> J
    J --> K{システムDB?}
    K -->|Yes| L{IncludeSystemDbs?}
    L -->|No| M[スキップ]
    L -->|Yes| N{固定ロール or public?}
    K -->|No| N
    N -->|Yes| O[スキップ・ログ出力]
    N -->|No| P{ShouldProcess確認}
    P -->|No| Q[スキップ]
    P -->|Yes| R[スキーマ所有権確認]
    R --> S{スキーマあり?}
    S -->|No| T[Drop実行]
    S -->|Yes| U[スキーマ処理]
    U --> V{オブジェクトあり?}
    V -->|Yes| W{Force?}
    W -->|No| X[警告・スキップ]
    W -->|Yes| Y[オーナーをdboに変更]
    V -->|No| Z{スキーマ名=ロール名?}
    Z -->|Yes| AA[スキーマDrop]
    Z -->|No| AB[オーナーをdboに変更]
    Y --> T
    AA --> T
    AB --> T
    T --> AC{成功?}
    AC -->|Yes| AD[Verboseログ]
    AC -->|No| AE[エラーログ]
    M --> AF{次のロール?}
    O --> AF
    Q --> AF
    X --> AF
    AD --> AF
    AE --> AF
    AF -->|Yes| J
    AF -->|No| AG[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 固定ロール保護 | IsFixedRole=Trueのロールは削除不可 | 常時 |
| BR-002 | publicロール保護 | publicロールは削除不可 | 常時 |
| BR-003 | システムDB除外 | デフォルトでシステムDBは処理対象外 | IncludeSystemDbs未指定時 |
| BR-004 | 同名スキーマ削除 | ロールと同名の空スキーマは削除 | スキーマにオブジェクトがない場合 |
| BR-005 | オーナー移譲 | その他のスキーマはdboに移譲 | オブジェクトなし、またはForce指定時 |

### 計算ロジック

特に計算ロジックはありません。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| スキーマオーナー変更 | sys.schemas | UPDATE | スキーマのprincipal_idを更新 |
| スキーマ削除 | sys.schemas | DELETE | 空スキーマの削除 |
| ロール削除 | sys.database_principals | DELETE | ロールの削除 |

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

#### sys.database_principals

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | principal_id | 対象ロールのID | SMO Drop()で実行 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InputError | 入力エラー | SqlInstanceもInputObjectも未指定 | いずれかを指定 |
| InvalidInputType | タイプエラー | サポートされない入力タイプ | 正しいオブジェクトをパイプ |
| SchemaOwnsObjects | 依存エラー | スキーマにオブジェクトが存在 | -Forceを使用 |
| DropFailed | 削除エラー | Drop()の失敗 | エラー内容を確認 |

### リトライ仕様

エラー発生時はStop-Functionで処理を中断し、次のロールへ継続します。

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

SMOのDrop()およびAlter()メソッドによる暗黙的トランザクションで処理されます。

## パフォーマンス要件

通常のロール削除は1秒以内で完了します。スキーマ内オブジェクトの列挙に時間がかかる場合があります。

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

- ALTER ANY ROLE権限が必要
- スキーマオーナー変更にはALTER SCHEMA権限が必要
- ConfirmImpact=Highによるデフォルト確認プロンプト
- 監査ログによる操作追跡を推奨

## 備考

- ExcludeFixedRoleは内部で常にTrueに設定
- パイプライン入力による柔軟な操作が可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | DatabaseRole (SMO) | Microsoft.SqlServer.Management.Smo | SMOのDatabaseRoleクラスの構造 |

**読解のコツ**: DatabaseRoleオブジェクトは、Name、IsFixedRole、Parentプロパティを持ちます。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Remove-DbaDbRole.ps1 | `public/Remove-DbaDbRole.ps1` | 関数定義とパラメータバインディング |

**主要処理フロー**:
1. **100-114行目**: パラメータ定義
2. **116-120行目**: 入力検証
3. **126-149行目**: 入力タイプ別のロール取得

#### Step 3: 入力タイプ判定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Remove-DbaDbRole.ps1 | `public/Remove-DbaDbRole.ps1` | switch文による入力タイプ判定 |

**主要処理フロー**:
- **127-148行目**: switch文で4種類の入力タイプを処理
- **129-132行目**: DbaInstanceParameter → Get-DbaDbRole
- **137-139行目**: Database → パイプ経由Get-DbaDbRole
- **141-143行目**: DatabaseRole → 直接使用

#### Step 4: ロール削除処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Remove-DbaDbRole.ps1 | `public/Remove-DbaDbRole.ps1` | スキーマ処理とDrop実行 |

**主要処理フロー**:
- **151-227行目**: ロールループ処理
- **158-159行目**: システムDB・固定ロールチェック
- **162-193行目**: スキーマ所有権確認と処理
- **196-218行目**: スキーマAlter/Dropとロール削除

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

```
Remove-DbaDbRole
    │
    ├─ Get-DbaDbRole (入力タイプに応じて)
    │      └─ ExcludeFixedRole:$True
    │
    ├─ Schema.EnumOwnedObjects()
    │      └─ スキーマ内オブジェクト確認
    │
    ├─ Schema.Alter() / Schema.Drop()
    │      └─ スキーマオーナー変更/削除
    │
    └─ DatabaseRole.Drop()
           └─ ロール削除
```

### データフロー図

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

SqlInstance ─────────▶ タイプ判定 ──────────▶ Get-DbaDbRole
        or                                         │
InputObject                                        │
(Server/DB/Role)                                   ▼
                                             ロールコレクション
                                                   │
                                                   ▼
                                           ロールごとの処理
                                                   │
                                           スキーマ所有権確認
                                                   │
                                           Schema.Alter/Drop
                                                   │
                                           DatabaseRole.Drop()
                                                   │
                                                   ▼
                                           Verbose/Warningメッセージ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Remove-DbaDbRole.ps1 | `public/Remove-DbaDbRole.ps1` | ソース | メイン関数定義 |
| Get-DbaDbRole.ps1 | `public/Get-DbaDbRole.ps1` | ソース | ロール取得 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | インスタンス接続 |
| Stop-Function.ps1 | `private/functions/Stop-Function.ps1` | ソース | エラー処理 |
| Write-Message.ps1 | `private/functions/Write-Message.ps1` | ソース | メッセージ出力 |
