# 機能設計書 160-Import-DbaCsv

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおける `Import-DbaCsv` コマンドレットの機能設計を記述する。本機能は、CSVファイルをSQL Serverテーブルに高性能なバルクコピー操作でインポートするための機能である。

### 本機能の処理概要

.NETのSqlBulkCopyクラスを使用して、CSVデータを効率的にSQL Serverテーブルにロードする機能である。小規模なデータセットからギガバイト規模の大容量インポートまで対応し、トランザクション管理、自動テーブル作成、型推論、並列処理などの高度な機能を提供する。

**業務上の目的・背景**：ETLプロセス、データ移行、リファレンスデータのロードなど、多くの業務シナリオでCSVファイルからSQL Serverへのデータインポートが必要となる。従来のINSERT文ベースのインポートは大量データで性能問題を引き起こす。本機能は、SqlBulkCopyを活用した高速インポートと、適切なエラーハンドリング・トランザクション安全性を提供する。

**機能の利用シーン**：
- ETLプロセスでのデータロード
- データ移行プロジェクト
- リファレンスデータの一括登録
- テストデータの投入
- 外部システムからのデータ連携
- 定期的なデータ更新バッチ

**主要な処理内容**：
1. CSVファイルの読み込みと解析（圧縮ファイル対応）
2. テーブル存在確認と自動作成（オプション）
3. 型推論によるスキーマ生成（オプション）
4. SqlBulkCopyによる高速データ転送
5. トランザクション管理とエラーハンドリング
6. インポート後のカラムサイズ最適化

**関連システム・外部連携**：SQL Server Management Objects (SMO)、Microsoft.Data.SqlClient

**権限による制御**：対象テーブルへのINSERT権限、AutoCreateTable使用時はCREATE TABLE権限、Truncate使用時はALTER権限が必要。

## 関連画面

本機能はコマンドライン機能であり、直接的な関連画面は存在しない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | - |

## 機能種別

データインポート（バルクコピー）

## 入力仕様

### 入力パラメータ（主要）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Path | object[] | No | CSVファイルパス。パイプライン入力対応 | 存在するファイル |
| SqlInstance | DbaInstanceParameter[] | Yes | SQL Serverインスタンス | - |
| SqlCredential | PSCredential | No | SQL Server認証情報 | - |
| Database | string | Yes | インポート先データベース | - |
| Table | string | No | インポート先テーブル名（未指定時はファイル名） | - |
| Schema | string | No | スキーマ名（デフォルト: dbo） | - |
| Delimiter | string | No | 区切り文字（デフォルト: カンマ） | - |
| AutoCreateTable | switch | No | テーブル自動作成 | - |
| Truncate | switch | No | インポート前にTRUNCATE | - |
| BatchSize | int | No | バッチサイズ（デフォルト: 50000） | 正の整数 |
| NotifyAfter | int | No | 進捗通知間隔（デフォルト: 50000） | 正の整数 |
| NoTransaction | switch | No | トランザクション無効化 | - |
| SampleRows | int | No | 型推論用サンプル行数 | 正の整数 |
| DetectColumnTypes | switch | No | 全行スキャンで型推論 | - |
| Parallel | switch | No | 並列処理有効化 | - |

### 入力パラメータ（CSV解析オプション）

| パラメータ名 | 型 | 必須 | 説明 | デフォルト |
|-------------|-----|-----|------|-----------|
| NoHeaderRow | switch | No | 先頭行をデータとして扱う | false |
| Quote | char | No | 引用符文字 | " |
| Escape | char | No | エスケープ文字 | " |
| Comment | char | No | コメント行識別文字 | # |
| Encoding | string | No | ファイルエンコーディング | UTF8 |
| SkipRows | int | No | スキップ行数 | 0 |
| SkipEmptyLine | switch | No | 空行スキップ | false |
| SupportsMultiline | switch | No | 複数行フィールド対応 | false |

### 入力データソース

- CSVファイル（ファイルシステム）
- 圧縮CSVファイル（.csv.gz）
- パイプライン入力（FileInfo）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverホストコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全修飾インスタンス名 |
| Database | string | インポート先データベース名 |
| Table | string | インポート先テーブル名 |
| Schema | string | スキーマ名 |
| RowsCopied | int64 | コピーされた行数 |
| Elapsed | prettytimespan | 経過時間 |
| RowsPerSecond | decimal | 1秒あたりのインポート行数 |
| Path | string | インポート元CSVファイルパス |

### 出力先

- PowerShellパイプライン（PSCustomObject）
- コンソール出力（進捗表示）

## 処理フロー

### 処理シーケンス

```
1. ファイル検証
   └─ パス存在確認、区切り文字検証

2. SQL Server接続
   └─ Connect-DbaInstance

3. スキーマ確認/作成
   └─ スキーマ存在確認、必要に応じて作成

4. テーブル確認/作成
   ├─ 既存テーブル → 既存スキーマ使用
   ├─ AutoCreateTable → nvarchar(MAX)でテーブル作成
   └─ SampleRows/DetectColumnTypes → 型推論してテーブル作成

5. Truncate処理（オプション）
   └─ 既存データ削除

6. SqlBulkCopy設定
   └─ オプション設定、カラムマッピング

7. CSVReader初期化
   └─ 圧縮対応、エンコーディング設定

8. バルクコピー実行
   └─ WriteToServer、進捗コールバック

9. トランザクション完了
   └─ Commit/Rollback

10. カラム最適化（AutoCreateTable時）
    └─ nvarchar(MAX) → 適切なサイズに変更

11. 結果出力
    └─ 統計情報のPSCustomObject出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[ファイル存在確認]
    B --> C{ファイル存在?}
    C -->|No| D[エラー終了]
    C -->|Yes| E[SQL Server接続]
    E --> F{接続成功?}
    F -->|No| D
    F -->|Yes| G[トランザクション開始]
    G --> H{スキーマ存在?}
    H -->|No| I[スキーマ作成]
    H -->|Yes| J{テーブル存在?}
    I --> J
    J -->|No| K{AutoCreateTable?}
    K -->|No| D
    K -->|Yes| L{型推論?}
    L -->|Yes| M[スキーマ推論]
    L -->|No| N[nvarchar MAX テーブル作成]
    M --> O[推論型でテーブル作成]
    J -->|Yes| P{Truncate?}
    N --> P
    O --> P
    P -->|Yes| Q[TRUNCATE TABLE]
    P -->|No| R[SqlBulkCopy設定]
    Q --> R
    R --> S[CsvDataReader初期化]
    S --> T[WriteToServer]
    T --> U{成功?}
    U -->|Yes| V[Commit]
    U -->|No| W[Rollback]
    V --> X{nvarchar MAX?}
    W --> D
    X -->|Yes| Y[カラムサイズ最適化]
    X -->|No| Z[結果出力]
    Y --> Z
    Z --> AA[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | トランザクション包含 | 全操作は1トランザクション内で実行 | NoTransaction未指定時 |
| BR-002 | テーブル名推論 | Table未指定時はファイル名をテーブル名に使用 | Table未指定時 |
| BR-003 | スキーマデフォルト | Schema未指定時はdboを使用 | Schema未指定時 |
| BR-004 | 型推論優先度 | DetectColumnTypesはSampleRowsより優先 | 両方指定時 |
| BR-005 | 圧縮自動検出 | .gz拡張子で圧縮ファイルを自動検出 | 常時 |

### 計算ロジック

- **RowsPerSecond**: `TotalRows / ElapsedSeconds`
- **カラムサイズパディング**: 最大長に応じて16, 32, 64, 128, 256, 512, 1024, 2048, 4000/8000にパディング

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| スキーマ作成 | sys.schemas | INSERT | 新規スキーマ作成 |
| テーブル作成 | 指定テーブル | CREATE | 新規テーブル作成 |
| データ削除 | 指定テーブル | TRUNCATE | 既存データ削除 |
| データ挿入 | 指定テーブル | INSERT (BULK) | CSVデータのバルクインサート |
| カラム変更 | 指定テーブル | ALTER | nvarchar(MAX)サイズ最適化 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ConnectionError | 接続エラー | SQL Server接続失敗 | Stop-Functionで終了 |
| FileNotFound | ファイルエラー | CSVファイル不存在 | Stop-Functionで継続 |
| DelimiterNotFound | 検証エラー | 区切り文字がファイルに存在しない | Stop-Functionで終了 |
| BulkCopyError | インポートエラー | SqlBulkCopy失敗 | Rollback、Stop-Function |

### リトライ仕様

リトライは実装されていない。エラー発生時はRollbackして終了。

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

- デフォルト: 全操作を1トランザクションで包含
- スキーマ作成、テーブル作成、Truncate、バルクコピーが単一トランザクション
- エラー発生時は自動Rollback
- NoTransaction指定時はトランザクションなし（部分コミット可能）

## パフォーマンス要件

- SqlBulkCopyによる高速バルクインサート
- BatchSizeでメモリ使用量とパフォーマンスのバランス調整
- Parallelオプションで2-4倍の性能向上（大規模ファイル）
- TableLockオプションでロックオーバーヘッド削減

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

- SQL Server認証情報の適切な管理
- インポートデータの検証（悪意のあるデータ対策）
- 圧縮ファイルサイズ制限（圧縮爆弾対策: MaxDecompressedSize）

## 備考

- 最小要件: SQL Server 2005以上
- gzip圧縮ファイル（.csv.gz）対応
- マルチ文字区切りサポート（例: "::", "||"）
- 関連コマンド: Export-DbaCsv, Write-DbaDbTableData

---

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

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

### 推奨読解順序

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

本機能は多数のパラメータを持つ複雑な関数である。まず出力構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Import-DbaCsv.ps1 | `public/Import-DbaCsv.ps1` | 304-320行目の.OUTPUTSセクションで出力構造を確認 |

**読解のコツ**: 出力プロパティ（RowsCopied, Elapsed, RowsPerSecond等）の意味を理解する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Import-DbaCsv.ps1 | `public/Import-DbaCsv.ps1` | 511-580行目のパラメータ定義 |
| 2-2 | Import-DbaCsv.ps1 | `public/Import-DbaCsv.ps1` | 581-934行目のbeginブロック（ヘルパー関数定義） |

**主要処理フロー**:
1. **511-580行目**: 多数のパラメータ定義
2. **599-666行目**: New-SqlTable関数（nvarchar(MAX)テーブル作成）
3. **668-712行目**: New-SqlTableWithInferredSchema関数（型推論テーブル作成）
4. **714-749行目**: Get-InferredSchema関数（型推論実行）
5. **751-867行目**: Optimize-ColumnSize関数（カラムサイズ最適化）

#### Step 3: メイン処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Import-DbaCsv.ps1 | `public/Import-DbaCsv.ps1` | 935-1012行目のファイル検証とテーブル名推論 |
| 3-2 | Import-DbaCsv.ps1 | `public/Import-DbaCsv.ps1` | 1012-1156行目のスキーマ/テーブル作成 |
| 3-3 | Import-DbaCsv.ps1 | `public/Import-DbaCsv.ps1` | 1176-1401行目のSqlBulkCopy実行 |
| 3-4 | Import-DbaCsv.ps1 | `public/Import-DbaCsv.ps1` | 1470-1493行目の結果出力 |

**主要処理フロー**:
- **1017-1043行目**: SQL Server接続とトランザクション開始
- **1048-1066行目**: スキーマ存在確認と作成
- **1092-1155行目**: テーブル存在確認と作成（型推論含む）
- **1164-1174行目**: Truncate処理
- **1189-1260行目**: SqlBulkCopy設定とカラムマッピング
- **1262-1401行目**: CsvDataReader初期化とWriteToServer
- **1421-1428行目**: カラムサイズ最適化

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

```
Import-DbaCsv
    │
    ├─ [begin] ヘルパー関数定義
    │      ├─ New-SqlTable
    │      ├─ New-SqlTableWithInferredSchema
    │      ├─ Get-InferredSchema
    │      ├─ Optimize-ColumnSize
    │      ├─ ConvertTo-DotnetType
    │      └─ Get-TableDefinitionFromInfoSchema
    │
    ├─ [process] メイン処理
    │      ├─ ファイル検証
    │      │
    │      ├─ Connect-DbaInstance
    │      │
    │      ├─ BeginTransaction
    │      │
    │      ├─ スキーマ確認/作成
    │      │
    │      ├─ テーブル確認/作成
    │      │      ├─ New-SqlTable
    │      │      └─ New-SqlTableWithInferredSchema
    │      │
    │      ├─ TRUNCATE (オプション)
    │      │
    │      ├─ SqlBulkCopy設定
    │      │
    │      ├─ CsvDataReader初期化
    │      │
    │      ├─ WriteToServer
    │      │
    │      ├─ Commit/Rollback
    │      │
    │      └─ Optimize-ColumnSize (AutoCreateTable時)
    │
    └─ [end] クリーンアップ
```

### データフロー図

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

CSVファイル ───▶ ファイル読み込み
    │                  │
    │                  ▼
    │           圧縮展開（.gz時）
    │                  │
    │                  ▼
    │           CsvDataReader 初期化
    │                  │
    │                  ▼
    │           型マッピング（既存テーブル時）
    │                  │
    ├─────────────────▼
    │           SqlBulkCopy
    │                  │
SqlInstance ─────────▼
    │           SQL Server テーブル
    │                  │
Database ────────────▼
    │           トランザクション Commit
    │                  │
Table/Schema ────────▼
                 結果 PSCustomObject ───▶ パイプライン出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Import-DbaCsv.ps1 | `public/Import-DbaCsv.ps1` | ソース | メイン機能実装 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続 |
| Export-DbaCsv.ps1 | `public/Export-DbaCsv.ps1` | ソース | CSV出力（関連コマンド） |
| Write-DbaDbTableData.ps1 | `public/Write-DbaDbTableData.ps1` | ソース | テーブル書き込み（関連コマンド） |
| Stop-Function.ps1 | `private/functions/Stop-Function.ps1` | ソース | エラー処理ユーティリティ |
| Write-Message.ps1 | `private/functions/Write-Message.ps1` | ソース | ログ出力ユーティリティ |
| Write-ProgressHelper.ps1 | `private/functions/Write-ProgressHelper.ps1` | ソース | 進捗表示ユーティリティ |
| Get-AdjustedTotalRowsCopied.ps1 | `private/functions/Get-AdjustedTotalRowsCopied.ps1` | ソース | 行数調整（int32オーバーフロー対策） |
