# 機能設計書 83-Export-DbaCsv

## 概要

本ドキュメントは、dbatools PowerShellモジュールのExport-DbaCsv関数の機能設計を定義する。この関数は、SQL Serverのクエリ結果やテーブルデータを、オプションで圧縮可能なCSVファイルにエクスポートする高性能な機能を提供する。

### 本機能の処理概要

Export-DbaCsv は、SQL Serverからのデータをカスタマイズ可能なCSVファイルとしてエクスポートするコマンドレットである。GZip、Deflate、Brotli、ZLibなど複数の圧縮形式をサポートし、大規模データの効率的なエクスポートと保存を可能にする。

**業務上の目的・背景**：データベースからのデータエクスポートは、ETLプロセス、レポート作成、データアーカイブ、システム間のデータ連携など、多くの業務シナリオで必要とされる。本機能は、標準的なCSV出力に加え、圧縮オプションによるファイルサイズ削減、カスタム区切り文字やエンコーディング設定など、柔軟なエクスポート機能を提供する。特に大容量データの転送やアーカイブにおいて、圧縮機能は帯域幅とストレージコストの削減に貢献する。

**機能の利用シーン**：
- 定期的なデータエクスポートジョブでのETLプロセス
- 分析用データの抽出とBIツールへの連携
- 監査やコンプライアンス用のデータアーカイブ
- 開発・テスト環境へのサンプルデータ作成
- 大容量テーブルの圧縮バックアップ作成
- 外部システムへのデータ連携ファイル生成

**主要な処理内容**：
1. SQL Serverインスタンスへの接続確立（SqlInstance指定時）
2. クエリ実行またはテーブルデータの取得
3. CSVライターオプションの設定（区切り文字、引用符、エンコーディング等）
4. 圧縮形式の自動検出または指定形式の適用
5. CSVファイルへのデータ書き込み
6. エクスポート結果の統計情報出力

**関連システム・外部連携**：
- SQL Server Database Engine からのデータ取得
- ファイルシステムへのCSV出力
- Dataplat.Dbatools.Csv.Writer ライブラリの使用
- 各種圧縮ライブラリ（GZip、Deflate、Brotli、ZLib）

**権限による制御**：
- SQL Server側では対象データベースへの読み取り権限が必要
- ファイルシステム側では出力先ディレクトリへの書き込み権限が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 220 | CSVインポート/エクスポート | 主機能 | CSVファイルのエクスポート |

## 機能種別

データエクスポート / ファイル出力

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | 対象SQL Serverインスタンス | 接続可能なインスタンス名 |
| SqlCredential | PSCredential | No | 代替認証資格情報 | 有効なPSCredentialオブジェクト |
| Database | string | No | 対象データベース名 | Query/Table使用時は必須 |
| Query | string | No | 実行するT-SQLクエリ | 有効なSQLクエリ |
| Table | string | No | エクスポートするテーブル名 | スキーマ名.テーブル名形式対応 |
| InputObject | object[] | No | パイプライン入力オブジェクト | ValueFromPipeline対応 |
| Path | string | Yes | 出力ファイルパス | 有効なファイルパス |
| Delimiter | string | No | フィールド区切り文字 | デフォルト: カンマ |
| NoHeader | switch | No | ヘッダー行の抑制 | - |
| Quote | char | No | 引用符文字 | デフォルト: ダブルクォート |
| QuotingBehavior | string | No | 引用符の適用ルール | AsNeeded/Always/Never/NonNumeric |
| Encoding | string | No | 文字エンコーディング | ASCII/BigEndianUnicode/Unicode/UTF7/UTF8/UTF32 |
| NullValue | string | No | NULL値の表現文字列 | デフォルト: 空文字 |
| DateTimeFormat | string | No | 日時フォーマット | デフォルト: yyyy-MM-dd HH:mm:ss.fff |
| UseUtc | switch | No | UTCへの変換 | - |
| CompressionType | string | No | 圧縮形式 | None/GZip/Deflate/Brotli/ZLib |
| CompressionLevel | string | No | 圧縮レベル | Fastest/Optimal/SmallestSize/NoCompression |
| Append | switch | No | 既存ファイルへの追記 | - |
| NoClobber | switch | No | 上書き禁止 | - |
| EnableException | switch | No | 例外処理の有効化 | - |

### 入力データソース

- SQL Server: Query パラメータで指定したSQLクエリの結果
- SQL Server: Table パラメータで指定したテーブルの全データ
- パイプライン: InputObject パラメータで受け取るPowerShellオブジェクト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Path | string | 出力されたCSVファイルのフルパス |
| RowsExported | int | エクスポートされた行数 |
| FileSizeBytes | long | 出力ファイルサイズ（バイト） |
| FileSizeMB | double | 出力ファイルサイズ（MB、小数点2桁） |
| CompressionType | string | 適用された圧縮形式 |
| Elapsed | TimeSpan | エクスポート処理にかかった時間 |
| RowsPerSecond | double | 1秒あたりの処理行数 |

### 出力先

- ファイルシステム: 指定されたPathにCSVファイルを出力
- PowerShellパイプライン: エクスポート結果のサマリーオブジェクト

## 処理フロー

### 処理シーケンス

```
1. パラメータ検証
   ├─ SqlInstance指定時はQuery/Tableのいずれかが必要
   ├─ Query/Tableの同時指定は不可
   └─ Database指定の確認

2. 圧縮形式の自動検出
   └─ ファイル拡張子から圧縮形式を判定（.gz → GZip等）

3. CSVライターオプションの設定
   ├─ 区切り文字、引用符、エンコーディング等
   ├─ 圧縮形式と圧縮レベル
   └─ Append時のヘッダー抑制

4. データ取得と書き込み
   ├─ SQL Serverからの場合: クエリ実行→DataReader経由で書き込み
   └─ InputObjectの場合: オブジェクトからプロパティ抽出→行単位書き込み

5. 結果統計の出力
   └─ エクスポート件数、ファイルサイズ、処理時間等
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{SqlInstance指定?}
    B -->|Yes| C[パラメータ検証]
    B -->|No| D{InputObject?}
    C --> E{Query or Table?}
    E -->|Query| F[SQLクエリ構築]
    E -->|Table| G[SELECT * クエリ構築]
    F --> H[接続・クエリ実行]
    G --> H
    H --> I[DataReader取得]
    I --> J[CSVWriter作成]
    J --> K[WriteFromReader実行]
    D -->|Yes| L[オブジェクト収集]
    L --> M[CSVWriter作成]
    M --> N[プロパティ抽出]
    N --> O[WriteHeader/WriteRow]
    K --> P[Dispose処理]
    O --> P
    P --> Q{RowsWritten > 0?}
    Q -->|Yes| R[結果オブジェクト出力]
    Q -->|No| S[出力なし]
    R --> T[終了]
    S --> T
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | パラメータ排他制御 | QueryとTableは同時指定不可 | SqlInstance使用時 |
| BR-002 | Database必須 | SqlInstance使用時はDatabaseも必須 | SqlInstance使用時 |
| BR-003 | 圧縮形式自動検出 | 拡張子から圧縮形式を判定 | CompressionType未指定時 |
| BR-004 | Append時ヘッダー抑制 | 既存ファイルへの追記時はヘッダーを出力しない | Append且つファイル存在 |
| BR-005 | SmallestSizeフォールバック | Windows PowerShellではOptimalにフォールバック | PSEdition != Core |

### 計算ロジック

- RowsPerSecond = RowsExported / Elapsed.TotalSeconds
- FileSizeMB = [math]::Round(FileSizeBytes / 1MB, 2)

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| クエリ実行 | 任意 | SELECT | 指定クエリの実行 |
| テーブル読取 | 指定テーブル | SELECT | テーブル全行の読み取り |

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

読み取り専用の操作であり、データベースへの変更は発生しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ParameterError | 検証エラー | SqlInstance指定時にQuery/Table未指定 | パラメータを正しく指定 |
| ParameterError | 検証エラー | Query/Tableの同時指定 | いずれか一方のみを指定 |
| ParameterError | 検証エラー | Database未指定（SqlInstance使用時） | Databaseを指定 |
| FileExistsError | ファイルエラー | NoClobber指定時にファイル存在 | 別のパスを指定するかAppendを使用 |
| ConnectionError | 接続エラー | SQL Serverに接続できない | インスタンス名・認証情報を確認 |
| QueryError | 実行エラー | SQLクエリの実行失敗 | クエリ構文を確認 |

### リトライ仕様

自動リトライは実装されていない。エラー発生時はStop-Functionで処理を停止する。

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

読み取り専用操作のため、トランザクション制御は不要。ただし、大規模データの読み取り中は共有ロックが取得される可能性がある。

## パフォーマンス要件

- DataReaderを使用したストリーミング処理により、大規模データでもメモリ効率的に処理
- 圧縮処理はCPU負荷が発生するが、I/O削減により全体的なパフォーマンス向上が期待できる
- CompressionLevel=Fastestを使用することで圧縮処理の高速化が可能

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

- SqlCredential パラメータで代替認証資格情報を安全に渡すことが可能
- 出力ファイルには機密データが含まれる可能性があるため、適切なアクセス制御が必要
- 圧縮ファイルでも暗号化は行われないため、機密データの場合は別途暗号化を検討

## 備考

- Brotli圧縮とZLib圧縮は.NET 8以降でのみ使用可能
- SmallestSize圧縮レベルは.NET 6以降でのみ使用可能（それ以前はOptimalにフォールバック）
- UTF8エンコーディングはBOMなしで出力される

---

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

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

### 推奨読解順序

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

出力されるPSCustomObjectの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Export-DbaCsv.ps1 | `public/Export-DbaCsv.ps1` | 392-400行目で出力オブジェクトの構造を確認 |

**読解のコツ**: 出力は行数が0より大きい場合のみ返される。各プロパティはエクスポート処理の統計情報を提供する。

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

コマンドの入口となるパラメータ定義と検証ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Export-DbaCsv.ps1 | `public/Export-DbaCsv.ps1` | 164-192行目のparam()ブロック |
| 2-2 | Export-DbaCsv.ps1 | `public/Export-DbaCsv.ps1` | 194-209行目のbeginブロックでのパラメータ検証 |

**主要処理フロー**:
1. **196-209行目**: SqlInstance使用時のQuery/Table/Database必須チェック
2. **211-220行目**: 圧縮形式の自動検出（拡張子ベース）
3. **223-226行目**: NoClobber時のファイル存在チェック

#### Step 3: CSVライターオプション設定を理解する

CSVWriterOptionsオブジェクトの設定を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Export-DbaCsv.ps1 | `public/Export-DbaCsv.ps1` | 228-259行目のライターオプション設定 |

**主要処理フロー**:
- **229行目**: CsvWriterOptionsオブジェクトの作成
- **230-237行目**: 基本オプション設定（Delimiter、Quote、Header等）
- **239-244行目**: CompressionLevel互換性処理
- **247-254行目**: エンコーディング設定

#### Step 4: SQL Serverからのデータ取得を理解する

SQLクエリ実行とDataReader経由のデータ取得を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Export-DbaCsv.ps1 | `public/Export-DbaCsv.ps1` | 279-333行目のSQL処理 |

**主要処理フロー**:
- **281行目**: Connect-DbaInstanceで接続確立
- **288-300行目**: Query/Tableパラメータに応じたSQLの構築
- **308-316行目**: SqlCommandの作成とDataReader取得
- **319-324行目**: CsvWriter経由でのデータ書き込み

#### Step 5: InputObjectの処理を理解する

パイプライン入力オブジェクトの処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Export-DbaCsv.ps1 | `public/Export-DbaCsv.ps1` | 340-375行目のInputObject処理 |

**主要処理フロー**:
- **348-355行目**: 最初のオブジェクトからプロパティ名抽出
- **357-360行目**: ヘッダー出力
- **362-369行目**: 各オブジェクトの値を行として出力

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

```
Export-DbaCsv
    │
    ├─ Connect-DbaInstance（SqlInstance指定時）
    │      └─ SQL Server接続の確立
    │
    ├─ SqlCommand.ExecuteReader()
    │      └─ クエリ実行とDataReader取得
    │
    └─ Dataplat.Dbatools.Csv.Writer.CsvWriter
           ├─ WriteFromReader()
           │      └─ DataReaderからの直接書き込み
           │
           ├─ WriteHeader()
           │      └─ ヘッダー行の書き込み
           │
           └─ WriteRow()
                  └─ データ行の書き込み
```

### データフロー図

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

SqlInstance ───┬──▶ Connect-DbaInstance
               │           │
Query/Table ───┤           ▼
               │    SQLクエリ実行
               │           │
               │           ▼
               │    DataReader取得
               │           │
               │           ▼
               └──▶ CsvWriter.WriteFromReader()
                           │
InputObject ──────▶ CsvWriter.WriteHeader()
                           │
                    CsvWriter.WriteRow()
                           │
                           ▼
                    CSVファイル ──────────▶ ファイルシステム
                           │
                           ▼
                    PSCustomObject ──────▶ パイプライン出力
                    (統計情報)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Export-DbaCsv.ps1 | `public/Export-DbaCsv.ps1` | ソース | メイン関数定義 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続ユーティリティ |
| CsvWriter.cs | `bin/library/Dataplat.Dbatools.Csv.Writer.CsvWriter` | ライブラリ | CSV書き込みエンジン |
| CsvWriterOptions.cs | `bin/library/Dataplat.Dbatools.Csv.Writer.CsvWriterOptions` | ライブラリ | ライターオプション定義 |
| Stop-Function.ps1 | `private/functions/Stop-Function.ps1` | ソース | エラーハンドリング関数 |
| Write-Message.ps1 | `private/functions/Write-Message.ps1` | ソース | メッセージ出力関数 |
| Test-Bound.ps1 | `private/functions/Test-Bound.ps1` | ソース | パラメータバインド確認関数 |
