# 機能設計書 671-New-DbaDbTable

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおける `New-DbaDbTable` コマンドレットの機能設計を記載する。この機能はSQL Serverデータベースに新しいテーブルを作成するためのPowerShellベースのテーブル作成機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：データベース管理者（DBA）や開発者がSQL ServerにテーブルをプログラムでPowerShellから作成する必要がある場面は多い。T-SQLスクリプトを直接実行する代わりに、PowerShellのオブジェクト指向のアプローチでテーブル定義を行うことで、より直感的で保守性の高いインフラストラクチャ自動化を実現できる。また、既存のETLプロセスやCI/CDパイプラインとの統合が容易になる。

**機能の利用シーン**：
- データベース移行時に複数のデータベースに同一構造のテーブルを一括作成する場合
- 開発環境やテスト環境のセットアップ時にテーブル構造を自動構築する場合
- アプリケーションデプロイメントパイプラインでのスキーマ変更自動化
- メモリ最適化テーブル、テンポラルテーブル、外部テーブルなど高度なテーブル機能を活用する場合

**主要な処理内容**：
1. SQL Serverインスタンスへの接続確立
2. 対象データベースの取得とバリデーション
3. スキーマの存在確認（存在しない場合は自動作成）
4. SMO（SQL Server Management Objects）を使用したテーブルオブジェクト構築
5. カラム定義（ColumnMapハッシュテーブルまたはSMO Columnオブジェクト）の処理
6. デフォルト制約、Identity設定、データ型変換の適用
7. テーブルの作成実行（またはスクリプト生成）
8. エラー発生時のロールバック処理（テーブル・スキーマの削除）

**関連システム・外部連携**：SQL Server Management Objects (SMO)ライブラリを使用してSQL Serverと通信する。Connect-DbaInstanceを通じてMFA認証を含む各種認証方式をサポート。

**権限による制御**：テーブル作成には対象データベースへのCREATE TABLE権限が必要。スキーマが存在しない場合はCREATE SCHEMA権限も必要となる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | コマンドライン | 主画面 | PowerShellコンソールまたはスクリプトから実行 |

## 機能種別

CRUD操作（Create）/ DDL操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | 接続先SQL Serverインスタンス | 有効なインスタンス名 |
| SqlCredential | PSCredential | No | 代替認証情報 | 有効な資格情報 |
| Database | String[] | No | テーブル作成先データベース | 存在するデータベース名 |
| Name | String | No | 作成するテーブル名 | 有効なSQL Server識別子 |
| Schema | String | No | スキーマ名（デフォルト: dbo） | 有効なスキーマ名 |
| ColumnMap | hashtable[] | No | カラム定義ハッシュテーブル配列 | Name, Type必須 |
| ColumnObject | Column[] | No | SMO Columnオブジェクト配列 | 有効なSMOオブジェクト |
| InputObject | Database[] | No | パイプライン入力用データベースオブジェクト | Microsoft.SqlServer.Management.Smo.Database |
| AnsiNullsStatus | Switch | No | ANSI_NULLS設定 | - |
| ChangeTrackingEnabled | Switch | No | 変更追跡有効化 | - |
| IsMemoryOptimized | Switch | No | メモリ最適化テーブル | - |
| IsSystemVersioned | Switch | No | テンポラルテーブル | - |
| IsFileTable | Switch | No | FileTable作成 | - |
| IsExternal | Switch | No | 外部テーブル作成 | - |
| IsNode | Switch | No | グラフデータベースノードテーブル | SQL Server 2017以上 |
| IsEdge | Switch | No | グラフデータベースエッジテーブル | SQL Server 2017以上 |
| Passthru | Switch | No | スクリプト出力モード | - |
| EnableException | Switch | No | 例外有効化 | - |

### ColumnMapハッシュテーブルの構造

| キー | 型 | 必須 | 説明 |
|------|-----|-----|------|
| Name | String | Yes | カラム名 |
| Type | String | Yes | SQL Serverデータ型 |
| MaxLength | Int | No | 最大長（varchar, nvarchar等） |
| Precision | Int | No | 精度（decimal用） |
| Scale | Int | No | スケール（decimal用） |
| Nullable | Boolean | No | NULL許可フラグ |
| Default | Object | No | デフォルト値 |
| DefaultName | String | No | デフォルト制約名 |
| DefaultExpression | String | No | デフォルト式（NEWID()等） |
| DefaultString | String | No | 文字列デフォルト値 |
| Identity | Boolean | No | Identity列フラグ |
| IdentitySeed | Int | No | Identityシード値 |
| IdentityIncrement | Int | No | Identityインクリメント値 |

### 入力データソース

- PowerShellコマンドラインパラメータ
- パイプライン入力（Get-DbaDatabase経由）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | String | SQL Serverコンピュータ名 |
| InstanceName | String | インスタンス名 |
| SqlInstance | String | 完全修飾インスタンス名 |
| Database | String | データベース名 |
| Schema | String | スキーマ名 |
| Name | String | テーブル名 |
| Rows | Int | 行数（新規作成時は0） |
| Created | DateTime | 作成日時 |
| LastModified | DateTime | 最終更新日時 |

### 出力先

- PowerShellパイプライン（Microsoft.SqlServer.Management.Smo.Table）
- -Passthru指定時: T-SQLスクリプト文字列

## 処理フロー

### 処理シーケンス

```
1. パラメータバリデーション
   └─ SqlInstance指定時はDatabase, Nameも必須
2. データベース取得
   └─ Get-DbaDatabase経由でInputObjectに追加
3. 各データベースに対してループ処理
   └─ 既存テーブルチェック（Schema + Name）
4. テーブルSMOオブジェクト生成
   └─ New-Object Microsoft.SqlServer.Management.Smo.Table
5. テーブルプロパティ設定
   └─ バウンドパラメータを動的に適用
6. カラム処理
   └─ ColumnObject: 直接追加
   └─ ColumnMap: DataType変換→Column生成→デフォルト制約追加
7. スキーマ確認・作成
   └─ 存在しない場合は自動作成
8. テーブル作成実行
   └─ Passthru: Script()メソッド実行
   └─ 通常: Invoke-Create実行
9. エラー時ロールバック
   └─ テーブル・スキーマのDrop()
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{SqlInstance指定?}
    B -->|Yes| C{Database, Name指定?}
    C -->|No| D[エラー終了]
    C -->|Yes| E[Get-DbaDatabase]
    B -->|No| E
    E --> F[各DBループ開始]
    F --> G{テーブル存在?}
    G -->|Yes| H[スキップ/警告]
    G -->|No| I[SMO Table作成]
    I --> J[プロパティ設定]
    J --> K{ColumnObject?}
    K -->|Yes| L[Columns.Add]
    K -->|No| M[ColumnMap処理]
    M --> N[DataType変換]
    N --> O[Column生成]
    O --> P[デフォルト制約追加]
    P --> L
    L --> Q{スキーマ存在?}
    Q -->|No| R[スキーマ作成]
    Q -->|Yes| S{Passthru?}
    R --> S
    S -->|Yes| T[Script出力]
    S -->|No| U[Invoke-Create]
    U --> V{成功?}
    V -->|No| W[ロールバック]
    V -->|Yes| X[Get-DbaDbTable]
    T --> Y[終了]
    X --> Y
    W --> D
    H --> F
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 既存テーブル重複禁止 | 同一スキーマ・テーブル名が存在する場合はエラー | テーブル作成時 |
| BR-002 | スキーマ自動作成 | 指定スキーマが存在しない場合は自動作成 | スキーマ未存在時 |
| BR-003 | グラフ機能バージョン制限 | IsNode/IsEdgeはSQL Server 2017以上のみ | パラメータ指定時 |
| BR-004 | データ型変換ルール | varchar/nvarchar等はMaxLengthに基づきMAXまたは指定長 | ColumnMap処理時 |

### 計算ロジック

**デフォルト値の処理優先順位**：
1. DefaultExpression（式として評価）
2. DefaultString（文字列リテラルとして評価）
3. Default（データ型に応じて自動判定）

**データ型変換**：
- varchar/nvarchar/char/nchar/varbinary: MaxLength > 0 → 指定長、それ以外 → MAX
- decimal: Precision/Scale指定時 → decimal(p,s)、MaxLength指定時 → decimal(MaxLength)

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| テーブル作成 | 指定テーブル | CREATE TABLE | 新規テーブル作成 |
| スキーマ作成 | sys.schemas | CREATE SCHEMA | スキーマ未存在時 |

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

#### 指定テーブル

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| CREATE TABLE | ColumnMap/ColumnObject指定カラム | 指定されたデータ型・制約 | SMO経由 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 接続エラー | SQL Serverに接続できない | 接続情報確認 |
| - | 重複エラー | 同名テーブルが既に存在 | 別名使用または既存削除 |
| - | 権限エラー | CREATE TABLE/SCHEMA権限不足 | 権限付与 |
| - | バージョンエラー | IsNode/IsEdgeがSQL 2017未満 | パラメータ削除またはアップグレード |

### リトライ仕様

エラー発生時のリトライは実装されていない。ロールバック処理により作成途中のテーブル・スキーマは削除される。

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

SMOのCreate()メソッドを使用するため、個々のDDL操作は暗黙的トランザクションで実行される。テーブル作成失敗時は明示的にDrop()を呼び出してロールバックを実現。

## パフォーマンス要件

特定のパフォーマンス要件なし。SMO経由のDDL操作のため、大量テーブルの一括作成時はループ処理による逐次実行となる。

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

- SqlCredentialパラメータで資格情報を安全に渡すことが可能
- Windows認証、SQL認証、Active Directory認証をサポート
- MFA認証はConnect-DbaInstanceを事前に使用

## 備考

- SQL Server 2000からサポート（一部機能はバージョン依存）
- Get-DbaDbTableと組み合わせて作成結果を確認可能

---

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

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

### 推奨読解順序

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

まず、カラム定義に使用されるハッシュテーブル構造とSMOオブジェクトを理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | New-DbaDbTable.ps1 | `public/New-DbaDbTable.ps1` | 408-462行目: パラメータ定義でColumnMapのハッシュテーブル構造とColumnObjectのSMO型を確認 |

**読解のコツ**: ColumnMapハッシュテーブルはPowerShellの連想配列で、Type, MaxLength, Nullable等のキーを持つ。ColumnObjectはMicrosoft.SqlServer.Management.Smo.Column型の配列。

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

処理の起点となるprocess{}ブロックを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | New-DbaDbTable.ps1 | `public/New-DbaDbTable.ps1` | 463-473行目: processブロック開始、パラメータバリデーションとInputObject構築 |

**主要処理フロー**:
1. **464-469行目**: SqlInstance指定時はDatabase, Nameの必須チェック
2. **471-473行目**: SqlInstanceからGet-DbaDatabase経由でInputObjectに追加

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | New-DbaDbTable.ps1 | `public/New-DbaDbTable.ps1` | 475-612行目: メインのテーブル作成ループ |

**主要処理フロー**:
- **479-482行目**: 既存テーブルチェック
- **484行目**: SMO Tableオブジェクト生成
- **495-504行目**: 動的パラメータ適用（IsNode/IsEdgeのバージョンチェック含む）
- **506-508行目**: ColumnObjectの処理
- **510-564行目**: ColumnMapの処理（DataType変換、デフォルト制約）
- **567-571行目**: スキーマ存在確認・作成
- **573-590行目**: Passthru/通常モードの分岐実行
- **591-609行目**: エラー時ロールバック処理

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

```
New-DbaDbTable
    │
    ├─ Test-Bound (パラメータチェック)
    │
    ├─ Get-DbaDatabase (InputObject構築)
    │      └─ Connect-DbaInstance
    │
    ├─ Get-DbaDbSchema (スキーマ存在確認)
    │
    ├─ New-DbaScriptingOption (Passthru時)
    │
    ├─ Invoke-Create (テーブル/スキーマ作成)
    │
    └─ Get-DbaDbTable (作成結果取得)
```

### データフロー図

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

SqlInstance ─────────────────┐
Database ────────────────────┼──▶ Get-DbaDatabase ──▶ InputObject
SqlCredential ───────────────┘

Name ────────────────────────┐
Schema ──────────────────────┼──▶ New SMO Table ──▶ TableObject
ColumnMap/ColumnObject ──────┘
                                         │
                                         ▼
                              Column処理/DataType変換
                                         │
                                         ▼
                              スキーマ確認/作成
                                         │
                              ┌──────────┴──────────┐
                              ▼                      ▼
                       [Passthru]              [通常モード]
                              │                      │
                              ▼                      ▼
                       Script()              Invoke-Create()
                              │                      │
                              ▼                      ▼
                       T-SQL String         Get-DbaDbTable
                                                     │
                                                     ▼
                                              SMO.Table Object
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| New-DbaDbTable.ps1 | `public/New-DbaDbTable.ps1` | ソース | メイン機能実装 |
| Get-DbaDatabase.ps1 | `public/Get-DbaDatabase.ps1` | ソース | データベース取得 |
| Get-DbaDbTable.ps1 | `public/Get-DbaDbTable.ps1` | ソース | テーブル取得（結果確認用） |
| Get-DbaDbSchema.ps1 | `public/Get-DbaDbSchema.ps1` | ソース | スキーマ存在確認 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | 接続処理 |
| New-DbaDbTable.Tests.ps1 | `tests/New-DbaDbTable.Tests.ps1` | テスト | 単体テスト |
