# 画面設計書 221-バイナリファイル

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおけるバイナリファイル管理機能の設計仕様を定義する。SQL Serverデータベースに格納されたバイナリデータ（画像、ドキュメント等）のインポート・エクスポート・テーブル検出機能を提供するCLIインターフェースである。

### 本画面の処理概要

本機能は、SQL Serverテーブルに格納されたバイナリデータ（binary、varbinary、image型）とファイルシステム間の双方向データ転送を実現する。データベースに保存されたドキュメント、画像、実行ファイルなどのバイナリコンテンツを抽出したり、逆にファイルシステムからデータベースへインポートする処理を行う。

**業務上の目的・背景**：企業システムでは、ドキュメント管理システムやコンテンツ管理システムにおいて、ファイルをデータベースのBLOB列に格納するケースが多い。レガシーアプリケーションのマイグレーション、データ抽出、バックアップ、監査などの場面で、これらのバイナリデータを効率的にファイルシステムと連携させる必要がある。本機能はSQL Server Management Studioでは煩雑な操作を、PowerShellコマンドラインで効率的に実行可能にする。

**画面へのアクセス方法**：PowerShellコンソールから以下のコマンドを実行することでアクセスする。
- `Export-DbaBinaryFile` - バイナリデータをファイルとしてエクスポート
- `Import-DbaBinaryFile` - ファイルをデータベースにインポート
- `Get-DbaBinaryFileTable` - バイナリ列を含むテーブルを検出

**主要な操作・処理内容**：
1. バイナリデータを含むテーブルの自動検出（列のデータ型に基づく）
2. ファイル名列とバイナリデータ列の自動推測または明示的指定
3. ストリーミング方式による大容量ファイルの効率的な転送
4. 複数テーブル・複数データベースの一括処理
5. カスタムSQLクエリによる柔軟なデータ抽出

**画面遷移**：本機能はCLIコマンドであり、画面遷移は存在しない。ただし、`Get-DbaBinaryFileTable`の出力を`Export-DbaBinaryFile`にパイプラインで渡すことで、対話的なワークフローを構築できる。

**権限による表示制御**：SQL Serverへの接続権限および対象テーブルへのSELECT/INSERT権限が必要。Windows認証、SQL Server認証、Azure AD認証をサポート。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | Export-DbaBinaryFile | 主機能 | バイナリデータをファイルシステムにエクスポート |
| - | Import-DbaBinaryFile | 主機能 | ファイルをデータベーステーブルにインポート |
| - | Get-DbaBinaryFileTable | 補助機能 | バイナリ列を含むテーブルの検出と列情報の取得 |
| - | Get-DbaDbTable | 関連機能 | テーブルオブジェクトの取得（パイプライン入力用） |
| - | Connect-DbaInstance | 関連機能 | SQL Serverインスタンスへの接続確立 |

## 画面種別

CLIコマンド（PowerShell関数）

## URL/ルーティング

PowerShellコマンドレット：
- `Export-DbaBinaryFile`
- `Import-DbaBinaryFile`
- `Get-DbaBinaryFileTable`

## 入出力項目

### Export-DbaBinaryFile パラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|------|------|
| SqlInstance | DbaInstanceParameter[] | 条件付き | 対象SQL Serverインスタンス |
| SqlCredential | PSCredential | No | SQL Server認証用資格情報 |
| Database | string[] | No | 対象データベース名（ワイルドカード対応） |
| Table | string[] | No | 対象テーブル名（3パート名対応） |
| Schema | string[] | No | 対象スキーマ名 |
| Path | string | 条件付き | 出力先ディレクトリパス |
| FilePath | string | 条件付き | 単一ファイルの出力パス |
| FileNameColumn | string | No | ファイル名を格納する列名 |
| BinaryColumn | string | No | バイナリデータを格納する列名 |
| Query | string | No | カスタムSQLクエリ |
| InputObject | Table[] | No | パイプライン入力（テーブルオブジェクト） |
| EnableException | switch | No | 例外処理モードの切り替え |

### Import-DbaBinaryFile パラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|------|------|
| SqlInstance | DbaInstanceParameter[] | 条件付き | 対象SQL Serverインスタンス |
| SqlCredential | PSCredential | No | SQL Server認証用資格情報 |
| Database | string | 条件付き | 対象データベース名 |
| Table | string | 条件付き | 対象テーブル名 |
| Schema | string | No | 対象スキーマ名 |
| FilePath | FileInfo[] | 条件付き | インポートするファイルパス |
| Path | FileInfo[] | 条件付き | インポートするディレクトリパス |
| Statement | string | No | カスタムINSERT文 |
| FileNameColumn | string | No | ファイル名を格納する列名 |
| BinaryColumn | string | No | バイナリデータを格納する列名 |
| NoFileNameColumn | switch | No | ファイル名列を使用しない |
| InputObject | Table[] | No | パイプライン入力（テーブルオブジェクト） |
| EnableException | switch | No | 例外処理モードの切り替え |

### Get-DbaBinaryFileTable パラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|------|------|
| SqlInstance | DbaInstanceParameter[] | 条件付き | 対象SQL Serverインスタンス |
| SqlCredential | PSCredential | No | SQL Server認証用資格情報 |
| Database | string[] | No | 対象データベース名 |
| Table | string[] | No | 対象テーブル名 |
| Schema | string[] | No | 対象スキーマ名 |
| InputObject | Table[] | No | パイプライン入力（テーブルオブジェクト） |
| EnableException | switch | No | 例外処理モードの切り替え |

## 表示項目

### Export-DbaBinaryFile 出力

| 項目名 | 型 | 説明 |
|--------|-----|------|
| FullName | string | エクスポートされたファイルの完全パス |
| Name | string | ファイル名 |
| DirectoryName | string | ディレクトリパス |
| Extension | string | 拡張子 |
| Length | long | ファイルサイズ（バイト） |
| CreationTime | DateTime | 作成日時 |
| LastWriteTime | DateTime | 最終更新日時 |

### Import-DbaBinaryFile 出力

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | コンピュータ名 |
| InstanceName | string | インスタンス名 |
| SqlInstance | string | 完全インスタンス名 |
| Database | string | データベース名 |
| Table | string | テーブル名 |
| FilePath | string | インポートしたファイルパス |
| Status | string | 処理結果（Success等） |

### Get-DbaBinaryFileTable 出力

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | コンピュータ名 |
| InstanceName | string | インスタンス名 |
| SqlInstance | string | 完全インスタンス名 |
| Database | string | データベース名 |
| Schema | string | スキーマ名 |
| Name | string | テーブル名 |
| BinaryColumn | string | バイナリ列名 |
| FileNameColumn | string | ファイル名列名 |

## イベント仕様

### 1-Export実行

バイナリデータをファイルシステムにエクスポートする処理フロー：

1. パラメータ検証（PathとFilePathの排他チェック）
2. 出力ディレクトリの存在確認・作成
3. InputObjectがない場合はGet-DbaDbTableでテーブルオブジェクトを取得
4. 各テーブルに対して：
   - バイナリ列の自動検出またはBinaryColumnパラメータ使用
   - ファイル名列の自動検出またはFileNameColumnパラメータ使用
   - SQLクエリ構築とDataReader取得
   - ストリーミングによるバイナリデータの書き出し
5. FileInfoオブジェクトを返却

### 2-Import実行

ファイルをデータベーステーブルにインポートする処理フロー：

1. パラメータ検証（PathとFilePathの排他チェック）
2. ファイルの存在確認
3. Pathの場合は再帰的にファイル一覧を取得
4. InputObjectがない場合はGet-DbaDbTableでテーブルオブジェクトを取得
5. 各ファイルに対して：
   - FileStreamでファイルをオープン
   - BinaryReaderでバイト配列に読み込み
   - INSERT文の構築（StatementパラメータまたはAutomatic）
   - パラメータ化クエリの実行
6. 結果オブジェクトを返却

### 3-テーブル検出

バイナリ列を含むテーブルの検出処理フロー：

1. InputObjectがない場合はGet-DbaDbTableでテーブルオブジェクトを取得
2. 各テーブルの列を走査：
   - DataTypeがbinary/varbinary/imageの列を検出
   - 名前に"name"を含む列を検出
3. BinaryColumnとFileNameColumnプロパティを追加
4. 拡張されたテーブルオブジェクトを返却

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Export-DbaBinaryFile | 指定テーブル | SELECT | バイナリデータの読み取り |
| Import-DbaBinaryFile | 指定テーブル | INSERT | バイナリデータの挿入 |
| Get-DbaBinaryFileTable | sys.columns等 | SELECT | テーブル構造の読み取り |

### テーブル別更新項目詳細

#### 対象ユーザーテーブル（Import時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | FileNameColumn | ファイル名（Split-Pathで抽出） | NoFileNameColumn時は省略 |
| INSERT | BinaryColumn | ファイルのバイト配列 | @FileContentsパラメータ |

## メッセージ仕様

| 種別 | メッセージID | メッセージ内容 | 発生条件 |
|------|-------------|---------------|---------|
| Error | - | You cannot specify both -Path and -FilePath | PathとFilePathの両方指定時 |
| Error | - | You must specify either -Path or -FilePath | PathもFilePathも指定なし時 |
| Error | - | Multiple column names match the phrase 'name' | ファイル名列の自動検出で複数候補時 |
| Error | - | No column names match the phrase 'name' | ファイル名列の自動検出で候補なし時 |
| Error | - | Multiple columns have a binary datatype | バイナリ列の自動検出で複数候補時 |
| Error | - | No columns have a binary datatype | バイナリ列の自動検出で候補なし時 |
| Error | - | Path does not exist | 指定パスが存在しない時 |
| Error | - | FilePath must be one or more files, not a directory | FilePathにディレクトリ指定時 |
| Verbose | - | Found N tables | 検出されたテーブル数 |
| Verbose | - | Query: ... | 実行されるSQLクエリ |
| Verbose | - | Importing filename | インポート中のファイル名 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 接続エラー | Stop-Functionで処理中断、エラーメッセージ表示 |
| テーブル取得失敗 | Stop-Functionで処理中断 |
| ファイル書き込み失敗 | finallyブロックでリソース解放、Continue処理 |
| ファイル読み込み失敗 | Stop-Functionでエラー表示、Continue処理 |
| SQL実行エラー | Stop-Functionでエラー表示、Continue処理 |

## 備考

- ストリームバッファサイズは8192バイトで固定
- 大容量ファイルはストリーミング方式で効率的に処理
- SQL Server 2000以降をサポート
- Windows/Linux両方のSQL Serverインスタンスに対応
- パイプライン処理による大規模一括処理が可能

---

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

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

### 推奨読解順序

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

バイナリファイル操作で使用されるデータ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Export-DbaBinaryFile.ps1 | `public/Export-DbaBinaryFile.ps1` | 出力型System.IO.FileInfoの構造、パラメータ定義 |
| 1-2 | Import-DbaBinaryFile.ps1 | `public/Import-DbaBinaryFile.ps1` | PSCustomObject出力の構造、パラメータ定義 |
| 1-3 | Get-DbaBinaryFileTable.ps1 | `public/Get-DbaBinaryFileTable.ps1` | 拡張されたTableオブジェクトの構造 |

**読解のコツ**: PowerShellの`[CmdletBinding()]`属性、パラメータ属性（Mandatory, ValueFromPipeline等）、出力型に注目する。

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

各コマンドのエントリーポイントとパラメータ検証を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Export-DbaBinaryFile.ps1 | `public/Export-DbaBinaryFile.ps1` | beginブロック（144-158行目）でのパラメータ検証とディレクトリ作成 |
| 2-2 | Import-DbaBinaryFile.ps1 | `public/Import-DbaBinaryFile.ps1` | processブロック冒頭（140-175行目）でのパラメータ検証とファイル存在確認 |

**主要処理フロー**:
1. **144-147行目**: PathとFilePathの排他チェック
2. **149-151行目**: いずれかのパス指定が必須であることの検証
3. **152-157行目**: 出力ディレクトリの存在確認と作成

#### Step 3: テーブル検出ロジックを理解する

バイナリ列とファイル名列の自動検出ロジックを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaBinaryFileTable.ps1 | `public/Get-DbaBinaryFileTable.ps1` | 118-131行目での列検出とプロパティ追加 |
| 3-2 | Export-DbaBinaryFile.ps1 | `public/Export-DbaBinaryFile.ps1` | 180-198行目での列自動検出ロジック |

**主要処理フロー**:
- **120行目**: DataType.Nameがbinary/imageにマッチする列を検出
- **121行目**: 列名に"Name"を含む列をファイル名候補として検出
- **129-130行目**: Add-Memberでテーブルオブジェクトに追加プロパティ付与

#### Step 4: バイナリデータ転送処理を理解する

ストリーミング方式のデータ転送処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Export-DbaBinaryFile.ps1 | `public/Export-DbaBinaryFile.ps1` | 210-246行目のDataReaderとFileStreamによるエクスポート |
| 4-2 | Import-DbaBinaryFile.ps1 | `public/Import-DbaBinaryFile.ps1` | 220-267行目のBinaryReaderとパラメータ化クエリによるインポート |

**主要処理フロー（Export）**:
- **202行目**: バッファサイズを8192バイトに設定
- **212行目**: ExecuteReaderでDataReader取得
- **225-237行目**: GetBytesでストリーミング読み取り、BinaryWriterで書き出し

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

```
Export-DbaBinaryFile
    |
    +-- Get-DbaDbTable（InputObjectがない場合）
    |       +-- Connect-DbaInstance
    |
    +-- ExecuteReader（SQLクエリ実行）
    |
    +-- FileStream/BinaryWriter（ファイル書き出し）

Import-DbaBinaryFile
    |
    +-- Get-DbaDbTable（InputObjectがない場合）
    |       +-- Connect-DbaInstance
    |
    +-- FileStream/BinaryReader（ファイル読み込み）
    |
    +-- ExecuteScalar（INSERTクエリ実行）

Get-DbaBinaryFileTable
    |
    +-- Get-DbaDbTable（InputObjectがない場合）
    |       +-- Connect-DbaInstance
    |
    +-- Add-Member（プロパティ追加）
    |
    +-- Select-DefaultView（出力整形）
```

### データフロー図

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

【Export処理】
SQL Server Table -------> ExecuteReader -------> FileStream -------> ファイルシステム
(binary/varbinary列)      DataReader取得          ストリーム書出      (.jpg, .pdf等)

【Import処理】
ファイルシステム -------> BinaryReader -------> パラメータ化 -------> SQL Server Table
(.jpg, .pdf等)           バイト配列読込        INSERT実行           (binary/varbinary列)

【テーブル検出】
SQL Server -------> Get-DbaDbTable -------> 列型フィルタ -------> 拡張Tableオブジェクト
(sys.columns等)    Tableオブジェクト取得    binary/image検出     (BinaryColumn付加)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Export-DbaBinaryFile.ps1 | `public/Export-DbaBinaryFile.ps1` | ソース | バイナリデータエクスポート機能 |
| Import-DbaBinaryFile.ps1 | `public/Import-DbaBinaryFile.ps1` | ソース | バイナリデータインポート機能 |
| Get-DbaBinaryFileTable.ps1 | `public/Get-DbaBinaryFileTable.ps1` | ソース | バイナリテーブル検出機能 |
| Get-DbaDbTable.ps1 | `public/Get-DbaDbTable.ps1` | ソース | テーブルオブジェクト取得（依存） |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続確立（依存） |
