# 機能設計書 114-Get-DbaDbUdf

## 概要

本ドキュメントは、SQL Serverデータベースからユーザー定義関数（UDF）およびユーザー定義集計（User Defined Aggregates）を取得するための機能設計書である。

### 本機能の処理概要

**業務上の目的・背景**：ユーザー定義関数はデータベース内のカスタムビジネスロジックを実装する重要なオブジェクトである。マイグレーション計画、コード依存関係の分析、セキュリティ監査、パフォーマンスレビューにおいて、これらのオブジェクトの棚卸しが必要となる。システムデータベースには100以上のシステムUDFが含まれることがあり、カスタムロジックの特定を困難にしている。本機能は、効率的なフィルタリングとメタデータ取得を提供する。

**機能の利用シーン**：
- データベースマイグレーション時のカスタムコード棚卸し
- コード依存関係の分析
- セキュリティおよびパフォーマンス監査
- CLRアセンブリベースの関数の特定
- 特定スキーマに属する関数の一覧取得

**主要な処理内容**：
1. 対象SQL Serverインスタンスへ接続
2. アクセス可能なデータベースを取得しフィルタリング
3. SMOのClearAndInitializeメソッドで効率的にプロパティを読み込み
4. UserDefinedFunctionsとUserDefinedAggregatesを結合
5. スキーマ、名前によるフィルタリングを適用
6. 各オブジェクトに接続情報を付加して出力

**関連システム・外部連携**：SQL Server Management Objects（SMO）を使用してデータベースオブジェクトにアクセス。

**権限による制御**：データベースへの読み取り権限が必要。UserDefinedFunctionsおよびUserDefinedAggregatesコレクションへのアクセス権が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | PowerShellコマンドラインインターフェースのみ |

## 機能種別

データ参照（SMOオブジェクト取得）/ メタデータ取得

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | Yes | 対象SQL Serverインスタンス（パイプライン可） | 接続可能なインスタンス名 |
| SqlCredential | PSCredential | No | 代替認証資格情報 | 有効なWindows/SQL認証資格情報 |
| Database | object[] | No | 対象データベース名（ワイルドカード対応） | 存在するデータベース名 |
| ExcludeDatabase | object[] | No | 除外するデータベース名 | 存在するデータベース名 |
| ExcludeSystemUdf | switch | No | システムUDFを除外 | - |
| Schema | string[] | No | 対象スキーマ名 | 存在するスキーマ名 |
| ExcludeSchema | string[] | No | 除外するスキーマ名 | 存在するスキーマ名 |
| Name | string[] | No | 対象UDF名（ワイルドカード対応） | 存在するUDF名 |
| ExcludeName | string[] | No | 除外するUDF名 | 存在するUDF名 |
| EnableException | switch | No | 例外を発生させるかどうか | - |

### 入力データソース

- SqlInstanceパラメータ: ユーザー入力またはパイプライン（必須）
- フィルタパラメータ: オプションの絞り込み条件

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| Database | string | データベース名 |
| Schema | string | スキーマ名 |
| CreateDate | datetime | 作成日時 |
| DateLastModified | datetime | 最終更新日時 |
| Name | string | UDF名または集計名 |
| DataType | string | 戻り値のデータ型 |

### 出力先

- PowerShellパイプライン（標準出力）
- Microsoft.SqlServer.Management.Smo.UserDefinedFunction または Microsoft.SqlServer.Management.Smo.UserDefinedAggregate として返却

## 処理フロー

### 処理シーケンス

```
1. processブロック開始
   └─ 各SqlInstanceについてループ処理
      ├─ 1.1 Connect-DbaInstance で接続
      ├─ 1.2 アクセス可能なデータベースを取得
      ├─ 1.3 Database/ExcludeDatabase フィルタ適用
      └─ 1.4 各データベースについてループ処理
             ├─ ClearAndInitialize でUDFプロパティを初期化
             ├─ ClearAndInitialize でUDAプロパティを初期化
             ├─ ExcludeSystemUdf フィルタ適用
             ├─ UDFとUDAを結合
             ├─ Schema/ExcludeSchema フィルタ適用
             ├─ Name/ExcludeName フィルタ適用
             └─ 接続情報を付加して出力
2. エラー処理
   └─ 接続失敗時は Stop-Function で次のインスタンスへ
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{SqlInstanceをループ}
    B --> C[Connect-DbaInstance]
    C --> D{接続成功?}
    D -->|No| E[Stop-Function]
    E --> B
    D -->|Yes| F[アクセス可能DB取得]
    F --> G[Database/ExcludeDBフィルタ]
    G --> H{各DBをループ}
    H --> I[UDF ClearAndInitialize]
    I --> J[UDA ClearAndInitialize]
    J --> K{ExcludeSystemUdf?}
    K -->|Yes| L[システムUDF除外]
    K -->|No| M[UDF + UDA 結合]
    L --> M
    M --> N{UDF/UDA存在?}
    N -->|No| O[警告出力]
    O --> H
    N -->|Yes| P[Schema/ExcludeSchemaフィルタ]
    P --> Q[Name/ExcludeNameフィルタ]
    Q --> R{各UDFをループ}
    R --> S[接続情報付加]
    S --> T[Select-DefaultView]
    T --> R
    R --> H
    H --> B
    B --> U[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | アクセス可能DB | IsAccessible = true のデータベースのみ対象 | 常時 |
| BR-002 | システムUDF除外 | ExcludeSystemUdf指定時はIsSystemObject = false のみ | ExcludeSystemUdf指定時 |
| BR-003 | UDA結合 | UserDefinedAggregatesは常にユーザー作成（システム集計は存在しない） | 常時 |
| BR-004 | 効率的プロパティ読み込み | ClearAndInitializeで必要なプロパティのみ一括読み込み | 常時 |

### 計算ロジック

特になし。メタデータ取得のみ。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| UDF取得 | sys.objects / sys.sql_modules | SELECT (SMO経由) | ユーザー定義関数のメタデータを取得 |
| UDA取得 | sys.objects / sys.assemblies | SELECT (SMO経由) | ユーザー定義集計のメタデータを取得 |

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

#### SMO UserDefinedFunctions コレクション

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | Schema, Name, CreateDate, DateLastModified, DataType, IsSystemObject | ClearAndInitialize | 一括読み込み |

#### SMO UserDefinedAggregates コレクション

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | Schema, Name, CreateDate, DateLastModified, DataType | ClearAndInitialize | IsSystemObjectなし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ConnectionError | SQL Server接続失敗 | Stop-Function でエラー出力、次のインスタンスへ |
| - | 情報メッセージ | UDF/UDAが存在しない | Write-Message で情報出力、次のDBへ |

### リトライ仕様

リトライ処理は実装されていない。接続エラー時は当該インスタンスをスキップして次を処理。

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

読み取り専用操作のため、トランザクション管理は不要。

## パフォーマンス要件

- ClearAndInitializeにより必要なプロパティのみを一括クエリで取得
- 大量のUDFがある場合でも効率的に動作
- 注意: ClearAndInitializeは他の場所で読み込まれたプロパティをクリアする

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

- データベースへの読み取り権限が必要
- UDFのソースコード（Textプロパティ）も取得可能なため、機密コードへのアクセスに注意
- SQL認証使用時は資格情報の安全な管理が必要

## 備考

- UserDefinedAggregatesはIsSystemObjectプロパティを持たないため、ExcludeSystemUdfでは影響を受けない
- Select-DefaultViewで主要プロパティのみ表示するが、Select-Object * で全プロパティにアクセス可能
- CLR関数の場合、AssemblyName、ClassNameプロパティでアセンブリ情報を取得可能

---

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

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

### 推奨読解順序

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

本機能ではSMO UserDefinedFunctionおよびUserDefinedAggregateオブジェクトを使用する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaDbUdf.ps1 | `public/Get-DbaDbUdf.ps1` | 出力がSMOオブジェクトであることを確認（64行目 .OUTPUTS） |

**読解のコツ**: SMOのUserDefinedFunctionとUserDefinedAggregateは異なるクラスだが、共通プロパティを持つ。

#### Step 2: ClearAndInitializeの仕組みを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaDbUdf.ps1 | `public/Get-DbaDbUdf.ps1` | ClearAndInitialize呼び出し（152-157行目） |

**主要処理フロー**:
1. **154行目**: UDFに対するClearAndInitialize - 必要なプロパティを指定して一括読み込み
2. **157行目**: UDAに対するClearAndInitialize - IsSystemObjectを含まない

#### Step 3: フィルタリングロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaDbUdf.ps1 | `public/Get-DbaDbUdf.ps1` | 複数のフィルタ処理（159-188行目） |

**主要処理フロー**:
- **159-163行目**: UserDefinedFunctionsの取得とExcludeSystemUdfフィルタ
- **167行目**: UDFとUDAの結合（配列として）
- **174-188行目**: Schema、ExcludeSchema、Name、ExcludeNameフィルタの適用

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

```
Get-DbaDbUdf
    │
    ├─ Connect-DbaInstance
    │
    └─ 各データベースに対して
           │
           ├─ $db.UserDefinedFunctions.ClearAndInitialize()
           │
           ├─ $db.UserDefinedAggregates.ClearAndInitialize()
           │
           ├─ Where-Object フィルタ
           │      ├─ IsSystemObject (UDFのみ)
           │      ├─ Schema / ExcludeSchema
           │      └─ Name / ExcludeName
           │
           └─ ForEach-Object
                  ├─ Add-Member (ComputerName, InstanceName, SqlInstance, Database)
                  └─ Select-DefaultView
```

### データフロー図

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

SqlInstance ───────▶ Connect-DbaInstance ───▶ $server
                            │
                            ▼
                     $server.Databases
                            │
                            ▼
                     Where-Object IsAccessible
                            │
                            ▼
              ┌─────────────┴─────────────┐
              ▼                           ▼
     UserDefinedFunctions      UserDefinedAggregates
     ClearAndInitialize        ClearAndInitialize
              │                           │
              └─────────────┬─────────────┘
                            │
                            ▼
                     @() + @() 結合
                            │
                            ▼
                     各種フィルタ適用
                            │
                            ▼
                     Add-Member
                            │
                            ▼
                     Select-DefaultView ───▶ パイプライン出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaDbUdf.ps1 | `public/Get-DbaDbUdf.ps1` | ソース | メイン関数の実装 |
| Remove-DbaDbUdf.ps1 | `public/Remove-DbaDbUdf.ps1` | ソース | 関連機能：UDF削除 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続機能 |
