# 機能設計書 542-Copy-DbaSystemDbUserObject

## 概要

本ドキュメントは、SQL Serverのシステムデータベース（master, model, msdb）内のユーザー作成オブジェクトを別のインスタンスにコピーするPowerShell関数`Copy-DbaSystemDbUserObject`の機能設計書である。

### 本機能の処理概要

Copy-DbaSystemDbUserObjectは、DBAが一般的にシステムデータベースに保存するカスタムオブジェクト（メンテナンス用ストアドプロシージャ、監視用テーブル、カスタムトリガー、バックアップユーティリティ等）を、ソースサーバーからターゲットサーバーにコピーする機能を提供する。

**業務上の目的・背景**：多くのDBAはシステムデータベースにカスタムオブジェクトを作成してサーバー管理を効率化している。サーバー移行時やマルチサーバー環境でのツール標準化において、これらのオブジェクトを効率的にコピーする必要がある。手動コピーは時間がかかり、依存関係の見落としが発生しやすいため、本機能により自動化と一貫性を確保できる。

**機能の利用シーン**：
- SQL Serverインスタンスの移行プロジェクト
- 複数インスタンス間でのDBAツールの標準化
- 新規サーバーセットアップ時のベースライン構成
- modelデータベースのカスタマイズの複製（新規データベース作成時に反映）

**主要な処理内容**：
1. ソース・ターゲットサーバーへの接続確立
2. master, model, msdbの各システムデータベースからユーザーオブジェクトを抽出
3. スキーマ、テーブル、ビュー、ストアドプロシージャ、関数、トリガー等のコピー
4. 依存関係を考慮したオブジェクト移行（Transferクラス使用）
5. 既存オブジェクトの処理（スキップまたはForceで上書き）

**関連システム・外部連携**：SQL Server Management Objects (SMO)のTransferクラスを使用。Classic モードではバルク転送を実行。

**権限による制御**：ソースおよびターゲットSQL Serverインスタンスでsysadmin権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | なし（CLI専用機能） | - | PowerShellコマンドラインから実行 |

## 機能種別

データ連携 / オブジェクト管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Source | DbaInstanceParameter | Yes | ソースSQL Serverインスタンス | ValidateNotNullOrEmpty |
| SourceSqlCredential | PSCredential | No | ソース接続用資格情報 | 有効なPSCredential |
| Destination | DbaInstanceParameter[] | Yes | ターゲットSQL Serverインスタンス（複数指定可） | ValidateNotNullOrEmpty |
| DestinationSqlCredential | PSCredential | No | ターゲット接続用資格情報 | 有効なPSCredential |
| Force | switch | No | 既存オブジェクトを削除して再作成 | - |
| Classic | switch | No | レガシー転送モードを使用 | - |
| EnableException | switch | No | 例外を有効化 | - |

### 入力データソース

- master, model, msdbデータベースのユーザーオブジェクト
- Get-DbaModuleを使用したモジュール（ビュー、関数、プロシージャ等）の取得

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| DateTime | DbaDateTime | 操作実行時刻 |
| SourceServer | string | ソースサーバー名 |
| DestinationServer | string | ターゲットサーバー名 |
| Name | string | オブジェクト名（スキーマ名.オブジェクト名形式） |
| Type | string | オブジェクト種別とデータベース名（例："User table in master"） |
| Status | string | Successful/Skipped/Failed |
| Notes | string | 操作結果の詳細またはエラーメッセージ |

### 出力先

PowerShellパイプライン（MigrationObjectタイプ）。Classicモードでは出力なし。

## 処理フロー

### 処理シーケンス

```
1. ソースサーバー接続
   └─ Connect-DbaInstance + sysadmin権限チェック
2. ターゲットサーバー接続ループ
   └─ 各ターゲットに対してsysadmin権限チェック
3. システムデータベースループ（master, model, msdb）
   └─ 各DBのユーザーオブジェクト処理
4. スキーマのコピー
   └─ IsSystemObject=falseのスキーマを抽出・コピー
5. テーブルのコピー
   └─ IsSystemObject=falseのテーブルを抽出・コピー
6. モジュールのコピー（Get-DbaModule使用）
   └─ ビュー、関数、プロシージャ、トリガー、ルールを処理
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[ソースサーバー接続]
    B --> C{sysadmin?}
    C -->|No| D[エラー終了]
    C -->|Yes| E[ターゲットサーバーループ]
    E --> F{Classic モード?}
    F -->|Yes| G[Transferクラスでバルクコピー]
    F -->|No| H[システムDBループ]
    H --> I[スキーマ処理]
    I --> J[テーブル処理]
    J --> K[モジュール処理]
    K --> L{全DB完了?}
    L -->|No| H
    L -->|Yes| M{全ターゲット完了?}
    G --> M
    M -->|No| E
    M -->|Yes| N[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-542-01 | システムオブジェクト除外 | IsSystemObject=trueのオブジェクトは除外 | 常時 |
| BR-542-02 | 既存オブジェクトスキップ | Forceなしの場合、既存オブジェクトはスキップ | Force未指定時 |
| BR-542-03 | 依存関係解決 | WithDependencies=trueで依存オブジェクトも転送 | 常時 |
| BR-542-04 | Classicモード | レガシーバルク転送で全オブジェクトタイプを一括処理 | Classic指定時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| スキーマ作成 | sys.schemas | INSERT | ユーザースキーマの作成 |
| テーブル作成 | sys.tables | INSERT | ユーザーテーブルの作成 |
| モジュール作成 | sys.sql_modules | INSERT | プロシージャ、関数等の作成 |
| オブジェクト削除 | 各オブジェクト | DELETE | Forceオプション使用時 |

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

#### 各システムデータベース

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | 各オブジェクト定義 | ソースからスクリプト生成 | SMO Transfer経由 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ConnectionError | 接続エラー | SQL Server接続失敗 | 接続情報を確認 |
| - | 権限エラー | sysadminでない | 適切な権限を付与 |
| - | 削除エラー | Force時のオブジェクト削除失敗 | 依存関係を確認 |
| - | 作成エラー | オブジェクト作成失敗 | エラーメッセージ確認 |

### リトライ仕様

リトライ機能なし。エラー時は次のオブジェクトの処理を継続。

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

各オブジェクトの作成は個別のSMO操作として実行される。明示的なトランザクション制御は行わない。Classicモードでは一括転送のため、部分的な失敗が発生する可能性がある。

## パフォーマンス要件

特に定義なし。大量のオブジェクト移行時はネットワーク帯域を考慮する必要がある。

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

- ソース・ターゲット両方でsysadmin権限が必要
- システムデータベースへの書き込みを伴う操作
- 資格情報はPSCredentialオブジェクトで安全に受け渡し

## 備考

- Classicモードは互換性問題がある場合に使用するレガシーオプション
- Forceオプションは依存関係のあるオブジェクトでは失敗する可能性がある
- WhatIfおよびConfirmスイッチをサポート

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Copy-DbaSystemDbUserObject.ps1 | `public/Copy-DbaSystemDbUserObject.ps1` | 77-90行目のパラメータ定義を確認 |

#### Step 2: ヘルパー関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Copy-DbaSystemDbUserObject.ps1 | `public/Copy-DbaSystemDbUserObject.ps1` | 94-106行目のget-sqltypename関数 |

**読解のコツ**: この内部関数はSQL Serverオブジェクトタイプを人間が読みやすい名前に変換する。

#### Step 3: モダンモード処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Copy-DbaSystemDbUserObject.ps1 | `public/Copy-DbaSystemDbUserObject.ps1` | 135-369行目のモダンモード処理 |

**主要処理フロー**:
- **136-138行目**: システムDBとSMOオブジェクト取得
- **140-141行目**: ユーザーテーブルとスキーマのフィルタリング
- **143-199行目**: スキーマ処理ループ
- **201-257行目**: テーブル処理ループ
- **259-368行目**: モジュール（ビュー、プロシージャ等）処理ループ

#### Step 4: Classicモード処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Copy-DbaSystemDbUserObject.ps1 | `public/Copy-DbaSystemDbUserObject.ps1` | 370-421行目のClassicモード処理 |

**読解のコツ**: ClassicモードはSMO Transferクラスを使用した一括転送。エラー処理が緩い（空のcatchブロック）。

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

```
Copy-DbaSystemDbUserObject
    │
    ├─ Connect-DbaInstance (ソース接続)
    │
    ├─ Test-SqlSa (sysadmin権限チェック)
    │
    ├─ Connect-DbaInstance (ターゲット接続)
    │
    ├─ [モダンモード]
    │   ├─ SMO Transfer.ScriptTransfer() (スキーマ/テーブル)
    │   └─ Get-DbaModule (モジュール取得)
    │
    └─ [Classicモード]
        └─ SMO Transfer (バルク転送)
            ├─ CopyAllTables
            ├─ CopyAllViews
            ├─ CopyAllStoredProcedures
            └─ ...
```

### データフロー図

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

Source Server     ───▶ Connect-DbaInstance     ───▶ SMO Server Object
    │                                                      │
    ▼                                                      ▼
System DBs        ───▶ Get User Objects        ───▶ Object Collection
(master/model/msdb)                                        │
    │                                                      ▼
    ▼
Transfer Class    ───▶ ScriptTransfer()        ───▶ T-SQL Scripts
    │                                                      │
    ▼                                                      ▼
Destination       ───▶ Query($sql)             ───▶ MigrationObject Output
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Copy-DbaSystemDbUserObject.ps1 | `public/Copy-DbaSystemDbUserObject.ps1` | ソース | メイン関数実装 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続共通関数 |
| Get-DbaModule.ps1 | `public/Get-DbaModule.ps1` | ソース | データベースモジュール取得 |
| Test-SqlSa.ps1 | `private/functions/Test-SqlSa.ps1` | ソース | sysadmin権限チェック |
