# 機能設計書 642-Import-DbaBinaryFile

## 概要

本ドキュメントは、ファイルシステムからバイナリファイルを読み込み、SQL Serverデータベーステーブルに格納するdbatools PowerShellコマンド「Import-DbaBinaryFile」の機能設計書です。

### 本機能の処理概要

Import-DbaBinaryFileは、ディスク上のバイナリファイル（画像、ドキュメント、実行ファイルなど）を読み込み、SQL Serverテーブルのバイナリ型カラム（binary、varbinary、image）に格納するコマンドです。

**業務上の目的・背景**：ドキュメント管理システム、コンテンツ管理システム、アプリケーション統合シナリオにおいて、ファイルをデータベースに直接保存する必要があります。本機能により、手動でのバイナリデータ変換やT-SQLスクリプト作成の手間を省き、大量ファイルの一括インポートを効率的に実行できます。

**機能の利用シーン**：
- ドキュメント管理システムへのファイル一括登録
- 画像ファイルのデータベースアーカイブ
- レガシーシステムからのファイルデータ移行
- アプリケーションで使用するリソースファイルの格納
- バックアップ目的でのファイルデータベース化

**主要な処理内容**：
1. 入力パラメータの検証（Database/Table指定またはInputObject、Path/FilePathの排他チェック）
2. 対象テーブルの取得とカラム自動検出（バイナリ型カラム、名前カラム）
3. ファイルをバイト配列として読み込み
4. パラメータ化クエリでINSERT文を実行
5. 結果オブジェクトの出力

**関連システム・外部連携**：
- ファイルシステム（ローカル/ネットワークパス）
- SQL Serverインスタンス

**権限による制御**：対象テーブルへのINSERT権限が必要です。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLI専用 | 主機能 | コマンドライン実行のみ |

## 機能種別

データ登録（INSERT） / ファイルインポート

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | 条件付き | 対象SQL Serverインスタンス | InputObject未指定時に必要 |
| SqlCredential | PSCredential | No | SQL Server接続用資格情報 | 有効なPSCredential |
| Database | string | 条件付き | 対象データベース名 | InputObject未指定時に必要 |
| Table | string | 条件付き | 対象テーブル名 | InputObject未指定時に必要 |
| Schema | string | No | テーブルのスキーマ名 | - |
| Statement | string | No | カスタムINSERT文 | @FileContentsパラメータ必須 |
| FileNameColumn | string | No | ファイル名格納カラム名 | - |
| BinaryColumn | string | No | バイナリデータ格納カラム名 | - |
| NoFileNameColumn | switch | No | ファイル名カラムなしフラグ | - |
| InputObject | Microsoft.SqlServer.Management.Smo.Table[] | No | パイプラインからのテーブルオブジェクト | - |
| FilePath | System.IO.FileInfo[] | 条件付き | インポートするファイルパス | Pathと排他 |
| Path | System.IO.FileInfo[] | 条件付き | インポートするディレクトリパス | FilePathと排他 |
| EnableException | switch | No | エラー時に例外をスロー | - |

### 入力データソース

- ファイルシステム: FilePath（個別ファイル）またはPath（ディレクトリ再帰）
- パイプライン入力: Get-ChildItemからのFileInfoオブジェクト
- パイプライン入力: Get-DbaDbTableからのテーブルオブジェクト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverインスタンスのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なインスタンス名（コンピュータ\インスタンス形式） |
| Database | string | インポート先データベース名 |
| Table | string | インポート先テーブル名 |
| FilePath | string | インポート元ファイルのフルパス |
| Status | string | インポート操作の結果（"Success"） |

### 出力先

パイプライン出力（PSCustomObject）

## 処理フロー

### 処理シーケンス

```
1. パラメータ検証
   ├─ Database/TableまたはInputObjectの必須チェック
   ├─ PathとFilePathの排他チェック
   └─ Path/FilePathいずれか必須チェック

2. ファイルパスの解決
   ├─ FilePath指定: 存在確認、ディレクトリでないことを確認
   └─ Path指定: ディレクトリ存在確認、再帰的にファイル取得

3. テーブルオブジェクトの取得
   └─ InputObject未指定時: Get-DbaDbTableで取得

4. 各テーブルに対してループ
   ├─ Statement未指定時のカラム自動検出
   │   ├─ FileNameColumn: "Name"を含むカラムを検索
   │   └─ BinaryColumn: binary/varbinary/imageデータ型を検索
   └─ 各ファイルに対してループ
       ├─ FileStreamでファイルを開く
       ├─ BinaryReaderでバイト配列を読み込み
       ├─ INSERT文の構築（StatementまたはAutoDetect）
       ├─ パラメータ化クエリの実行
       ├─ リソースのクリーンアップ
       └─ 結果オブジェクトの出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{パラメータ検証}
    B -->|失敗| C[エラー終了]
    B -->|成功| D{Path指定?}
    D -->|Yes| E[Get-ChildItem -Recurse]
    D -->|No| F[FilePath使用]
    E --> G[テーブル取得]
    F --> G
    G --> H[テーブルループ]
    H --> I{カラム自動検出}
    I -->|失敗| J[Stop-Function]
    I -->|成功| K[ファイルループ]
    K --> L[FileStream作成]
    L --> M[BinaryReader作成]
    M --> N[バイト配列読み込み]
    N --> O[INSERT文構築]
    O --> P[ExecuteScalar実行]
    P --> Q[結果出力]
    Q --> R{次ファイル?}
    R -->|Yes| K
    R -->|No| S{次テーブル?}
    S -->|Yes| H
    S -->|No| T[終了]
    J --> T
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | カラム自動検出 | バイナリ型カラムと名前カラムを自動検出 | Statement未指定時 |
| BR-002 | 排他パラメータ | PathとFilePathは同時指定不可 | 常時 |
| BR-003 | 複数カラム検出時エラー | バイナリ/名前カラムが複数見つかった場合はエラー | カラム自動検出時 |
| BR-004 | NoFileNameColumn | ファイル名カラムなしでバイナリデータのみ格納 | NoFileNameColumn指定時 |
| BR-005 | カスタムStatement | @FileContentsパラメータが必須、@FileNameはオプション | Statement指定時 |

### 計算ロジック

特になし（バイナリデータはそのまま格納）

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ファイルインポート | 指定テーブル | INSERT | バイナリデータとファイル名をテーブルに挿入 |

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

#### ユーザー指定テーブル

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | FileNameColumn | Split-Path -Leaf したファイル名 | NoFileNameColumn時は省略 |
| INSERT | BinaryColumn | ファイルのバイト配列 | binary/varbinary/image型 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ValidationError | Database/Table未指定かつInputObject未指定 | パラメータを正しく指定 |
| - | ValidationError | PathとFilePath両方指定 | いずれか一方のみ指定 |
| - | ValidationError | PathもFilePath も未指定 | いずれか一方を指定 |
| - | FileNotFound | 指定ファイルが存在しない | ファイルパスを確認 |
| - | ColumnDetectionError | バイナリカラムが見つからない/複数 | BinaryColumn明示指定 |
| - | ColumnDetectionError | 名前カラムが見つからない/複数 | FileNameColumn明示指定 |
| - | SqlException | INSERT文実行エラー | テーブル定義とデータを確認 |

### リトライ仕様

リトライなし（エラー時はContinueでスキップして次ファイルを処理）

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

各ファイルのINSERT操作は独立したトランザクションとして実行（暗黙的トランザクション）

## パフォーマンス要件

- ファイルサイズに依存（大きなファイルはメモリ使用量増加）
- SQL Serverのvarbinary(max)制限内で動作（最大2GB）

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

- 対象テーブルへのINSERT権限が必要
- パラメータ化クエリによりSQLインジェクション対策済み
- 資格情報はPSCredentialオブジェクトで安全に管理

## 備考

- テーブル名に特殊文字が含まれる場合は角括弧[]でエスケープ
- 3パート命名（db.schema.table）をサポート
- ShouldProcess対応（WhatIf/Confirm）

---

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

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

### 推奨読解順序

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

出力オブジェクトは動的なPSCustomObjectで、固定のプロパティセットを持ちます。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Import-DbaBinaryFile.ps1 | `public/Import-DbaBinaryFile.ps1` | L259-267の出力オブジェクト定義 |

**読解のコツ**: 出力オブジェクトはL259-267で定義されており、テーブルオブジェクトのプロパティを利用しています。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Import-DbaBinaryFile.ps1 | `public/Import-DbaBinaryFile.ps1` | processブロック全体の流れ |

**主要処理フロー**:
1. **140-154行目**: パラメータ検証（Database/Table、Path/FilePath排他チェック）
2. **155-174行目**: Path/FilePathの存在確認とファイル一覧取得
3. **177-184行目**: InputObject未指定時のテーブル取得
4. **186-214行目**: カラム自動検出ロジック
5. **216-282行目**: ファイル処理ループ（読み込み、INSERT、結果出力）

#### Step 3: カラム自動検出ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Import-DbaBinaryFile.ps1 | `public/Import-DbaBinaryFile.ps1` | L195-213のカラム検出 |

**主要処理フロー**:
- **196行目**: 名前カラム検出（Name -match Name）
- **206行目**: バイナリカラム検出（DataType.Name -match "binary" -or -eq "image"）
- **197-202, 207-212行目**: 複数/ゼロ検出時のエラー処理

#### Step 4: バイナリファイル処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Import-DbaBinaryFile.ps1 | `public/Import-DbaBinaryFile.ps1` | L220-258のファイル処理 |

**主要処理フロー**:
- **221行目**: FileStream作成
- **224-225行目**: BinaryReaderでバイト配列読み込み
- **227-233行目**: INSERT文の動的構築
- **236-246行目**: SqlCommandでパラメータ化クエリ実行
- **248-257行目**: リソースクリーンアップ

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

```
Import-DbaBinaryFile
    │
    ├─ Test-FunctionInterrupt（処理中断チェック）
    │
    ├─ Get-DbaDbTable（テーブルオブジェクト取得）
    │      └─ Connect-DbaInstance
    │
    ├─ カラム自動検出
    │      ├─ FileNameColumn検出（Name -match Name）
    │      └─ BinaryColumn検出（DataType binary/varbinary/image）
    │
    ├─ ファイル処理ループ
    │      ├─ New-Object System.IO.FileStream
    │      ├─ New-Object System.IO.BinaryReader
    │      ├─ SqlConnectionObject.CreateCommand()
    │      └─ ExecuteScalar()
    │
    └─ Disconnect-DbaInstance
```

### データフロー図

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

FilePath/Path ─────────────┐
                           │
SqlInstance ───────────────┤
                           ├──▶ ファイル読み込み ────────────┐
Database ──────────────────┤          │                      │
                           │          ▼                      ▼
Table ─────────────────────┤    BinaryReader          PSCustomObject
                           │          │               (ComputerName,
InputObject ───────────────┘          ▼                InstanceName,
                                 byte[]                 SqlInstance,
                                      │                 Database,
                                      ▼                 Table,
                              INSERT文実行              FilePath,
                                      │                 Status)
                                      ▼
                              SQL Server Table
                              [バイナリカラム]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Import-DbaBinaryFile.ps1 | `public/Import-DbaBinaryFile.ps1` | ソース | メインコマンド実装 |
| Get-DbaDbTable.ps1 | `public/Get-DbaDbTable.ps1` | ソース | テーブルオブジェクト取得 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続 |
| Disconnect-DbaInstance.ps1 | `public/Disconnect-DbaInstance.ps1` | ソース | SQL Server切断 |
| Import-DbaBinaryFile.Tests.ps1 | `tests/Import-DbaBinaryFile.Tests.ps1` | テスト | パラメータ検証テスト |
