# 機能設計書 454-Remove-DbaReplArticle

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおける`Remove-DbaReplArticle`関数の機能設計を定義する。この関数はSQL Serverレプリケーションパブリケーションからアーティクル（テーブル、ビュー、ストアドプロシージャ等）を削除する。

### 本機能の処理概要

**業務上の目的・背景**：レプリケーション構成の変更時に、特定のオブジェクトのみを複製対象から除外する必要がある場合がある。本関数は、パブリケーション全体を解体せずに、個別のアーティクルを削除することを可能にする。これにより、運用中のレプリケーション構成の部分的な変更を効率的に行える。

**機能の利用シーン**：
- テーブル構造変更に伴うレプリケーション再構成時
- 不要になったオブジェクトのレプリケーション停止時
- パブリケーションのスリム化・最適化時
- CI/CD パイプラインでのレプリケーション構成更新時

**主要な処理内容**：
1. 対象アーティクルの特定（パラメータまたはパイプライン入力）
2. サブスクリプション存在確認（存在する場合は先にサブスクリプションから削除）
3. sp_dropsubscription実行（サブスクリプションがある場合）
4. アーティクルオブジェクトのRemove()メソッド呼び出し
5. 削除結果オブジェクトの出力

**関連システム・外部連携**：SQL Server Replication Management Objects (RMO)、T-SQL（sp_dropsubscription）

**権限による制御**：sysadminまたはdb_owner権限、およびパブリケーション管理者権限が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | SQL Server Management Studio - パブリケーションプロパティ | 参照画面 | アーティクル削除操作に相当 |

## 機能種別

CRUD操作（Delete） / レプリケーション構成変更

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No* | SQL Serverインスタンス | InputObjectと排他 |
| SqlCredential | PSCredential | No | SQL Server認証用資格情報 | 有効な認証情報 |
| Database | String | No* | パブリケーションデータベース | InputObjectと排他 |
| Publication | String | No* | パブリケーション名 | InputObjectと排他 |
| Schema | String | No | スキーマ名（デフォルト: 'dbo'） | 有効なスキーマ名 |
| Name | String | No* | アーティクル名 | InputObjectと排他 |
| InputObject | PSObject[] | No* | Get-DbaReplArticleからのパイプライン入力 | 有効なアーティクルオブジェクト |
| EnableException | Switch | No | 例外を有効化 | なし |

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

### 入力データソース

- パラメータ入力
- Get-DbaReplArticleからのパイプライン入力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | String | SQL Serverホストのコンピュータ名 |
| InstanceName | String | SQL Serverインスタンス名 |
| SqlInstance | String | フルSQL Serverインスタンス名 |
| Database | String | データベース名 |
| ObjectName | String | 削除されたオブジェクト名 |
| ObjectSchema | String | 削除されたオブジェクトのスキーマ |
| Status | String | 削除結果（"Removed"または エラーメッセージ） |
| IsRemoved | Boolean | 削除成功可否 |

### 出力先

パイプラインに削除結果オブジェクトを出力

## 処理フロー

### 処理シーケンス

```
1. 入力検証
   └─ SqlInstanceまたはInputObjectの存在確認
2. アーティクル情報の取得
   ├─ InputObject指定時: そのまま使用
   └─ パラメータ指定時: Get-DbaReplArticleで取得
3. 各アーティクルに対する削除処理（endブロックで実行）
   ├─ ShouldProcess確認
   ├─ パブリケーション情報取得（Get-DbaReplPublication）
   ├─ サブスクリプション存在確認
   │   └─ 存在する場合: sp_dropsubscription実行
   ├─ アーティクル存在確認（IsExistingObject）
   │   └─ 存在する場合: Remove()メソッド実行
   └─ 結果オブジェクトの構築と出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{SqlInstance or InputObject?}
    B -->|どちらもなし| C[エラー終了]
    B -->|あり| D{InputObject指定?}
    D -->|Yes| E[InputObjectを使用]
    D -->|No| F[Get-DbaReplArticle]
    E --> G[endブロック: foreach article]
    F --> G
    G --> H[ShouldProcess確認]
    H -->|Yes| I[Get-DbaReplPublication]
    H -->|No| R[スキップ]
    I --> J{サブスクリプション存在?}
    J -->|Yes| K[sp_dropsubscription実行]
    J -->|No| L{IsExistingObject?}
    K --> L
    L -->|Yes| M[Remove実行]
    L -->|No| N[エラー: アーティクル不存在]
    M --> O[Status = Removed]
    N --> P[Status = エラー]
    O --> Q[結果出力]
    P --> Q
    R --> Q
    Q --> S{次のアーティクル?}
    S -->|Yes| G
    S -->|No| T[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | サブスクリプション先削除 | サブスクリプションが存在する場合は、先にサブスクリプションからアーティクルを削除 | サブスクリプション存在時 |
| BR-002 | endブロック実行 | 削除処理はendブロックで実行し、パイプライン入力時のコレクション変更エラーを回避 | 常時適用 |
| BR-003 | ConfirmImpact High | 削除操作のため、確認プロンプトを表示 | -Confirmが有効な場合 |
| BR-004 | スナップショット無効化 | アーティクル削除により現在のスナップショットは無効になる | 常時適用 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| サブスクリプション削除 | MSsubscriptions | DELETE | sp_dropsubscriptionによる削除 |
| アーティクル削除 | sysarticles | DELETE | RMO Remove()による削除 |

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

#### sysarticles (publication database)

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | artid | 対象アーティクルID | アーティクル削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| N/A | 入力検証エラー | SqlInstanceとInputObject両方未指定 | いずれかを指定 |
| N/A | アーティクル不存在 | IsExistingObject = false | 正しいアーティクル名を指定 |
| N/A | 削除失敗 | Remove()メソッドでエラー | 権限確認、依存関係確認 |

### リトライ仕様

本関数にリトライ機能は実装されていない。

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

sp_dropsubscriptionとRemove()は個別トランザクションで実行。途中でエラーが発生した場合、それ以前の変更は維持される。

## パフォーマンス要件

アーティクル削除は通常数秒で完了。大量のアーティクルをパイプラインで削除する場合は、処理時間が増加する。

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

- sysadminまたはdb_owner権限が必要
- SqlCredentialはSecureStringとして処理
- ConfirmImpact = 'High'により、誤操作を防止

## 備考

- アーティクル削除後、パブリケーションデータベースからオブジェクト自体は削除されない
- サブスクリプションデータベースのオブジェクトも削除されない（手動でDROP必要）
- 削除後は新しいスナップショットの生成が必要
- DropObjectOnSubscriberパラメータはコメントアウトされている（104行目）

---

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

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

### 推奨読解順序

#### Step 1: 関数構造とパラメータを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Remove-DbaReplArticle.ps1 | `public/Remove-DbaReplArticle.ps1` | param()ブロック（96-108行目） |

**読解のコツ**: `ConfirmImpact = 'High'`は削除操作の重要度を示し、-Confirmなしでも確認プロンプトが表示される。

#### Step 2: 入力処理（processブロック）を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Remove-DbaReplArticle.ps1 | `public/Remove-DbaReplArticle.ps1` | processブロック（115-129行目） |

**主要処理フロー**:
1. **116-118行目**: SqlInstanceとInputObject両方未指定時のエラー
2. **121-122行目**: InputObject指定時は配列に追加
3. **124-128行目**: パラメータ指定時はGet-DbaReplArticleで取得

#### Step 3: 削除処理（endブロック）を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Remove-DbaReplArticle.ps1 | `public/Remove-DbaReplArticle.ps1` | endブロック（131-170行目） |

**主要処理フロー**:
- **134行目**: foreachでアーティクルをループ
- **135行目**: ShouldProcess確認
- **148-153行目**: サブスクリプション確認とsp_dropsubscription実行
- **155-159行目**: IsExistingObject確認とRemove()実行
- **160-161行目**: 成功時のStatus設定

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

```
Remove-DbaReplArticle
    │
    ├─ [begin] Add-ReplicationLibrary
    │
    ├─ [process] Get-DbaReplArticle (パラメータ指定時)
    │
    └─ [end] foreach (article)
           │
           ├─ Get-DbaReplPublication
           │      └─ サブスクリプション情報取得
           │
           ├─ Invoke-DbaQuery (sp_dropsubscription)
           │      └─ サブスクリプションがある場合
           │
           └─ [RMO] Article.Remove()
```

### データフロー図

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

SqlInstance/InputObject ────▶ 入力検証 ─────────────────────────────▶ エラー（両方なし）
                                   │
InputObject ────────────────▶ 配列に追加 ─────────────────────────────┐
                                   │                                  │
パラメータ ──────────────────▶ Get-DbaReplArticle ───────────────────┤
                                   │                                  │
                             foreach (article) ◀──────────────────────┘
                                   │
                             Get-DbaReplPublication ──────────────────┐
                                   │                                  │
                             サブスクリプション確認 ◀─────────────────┘
                                   │
                                   ├─ (存在) sp_dropsubscription ─────▶ サブスクリプション削除
                                   │
                             IsExistingObject確認
                                   │
                                   └─ (存在) Remove() ────────────────▶ PSCustomObject
                                                                        (Status, IsRemoved)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Remove-DbaReplArticle.ps1 | `public/Remove-DbaReplArticle.ps1` | ソース | メイン関数定義 |
| Get-DbaReplArticle.ps1 | `public/Get-DbaReplArticle.ps1` | ソース | アーティクル情報取得 |
| Get-DbaReplPublication.ps1 | `public/Get-DbaReplPublication.ps1` | ソース | パブリケーション情報取得 |
| Add-DbaReplArticle.ps1 | `public/Add-DbaReplArticle.ps1` | ソース | 対となるアーティクル追加機能 |
