Oracle PL/SQLには、複数の値をまとめて扱うためのコレクション型があります。代表的なものとして、連想配列、VARRAY、そしてNESTED TABLE(ネステッド・テーブル、ネスト表)があります。
NESTED TABLEはPL/SQLで複数要素を保持できるコレクション型の一つで、要素数を固定せずに増減できる点が特徴です。また、SQLレベルで型を定義すれば、表の列として保存したり、TABLE()演算子を使って行のように扱ったりすることもできます。
ここではNESTED TABLEの基本構文から、VARRAYや連想配列との違い、EXTENDやDELETEを使った操作方法まで、具体例を交えて整理します。
- Oracle PL/SQLにはNESTED TABLEというコレクション型がある
- NESTED TABLEの基本的な書き方
- NESTED TABLEは要素数を増やせる
- DELETEを使って途中の要素を削除できる
- NESTED TABLEで使える主なコレクションメソッド
- Oracle PL/SQLのコレクション型は主に3種類
- NESTED TABLEとVARRAYの違い
- NESTED TABLEと連想配列の違い
- SQLレベルでNESTED TABLE型を定義することもできる
- テーブルの列としてNESTED TABLEを保存できる
- TABLE演算子を使うとコレクションを行として扱える
- BULK COLLECTと組み合わせることもある
- NESTED TABLEは「表の中に普通の表がそのまま入る」という意味ではない
- NESTED TABLEを選ぶべき場面
- まとめ:NESTED TABLEはOracle PL/SQLの代表的なコレクション型
Oracle PL/SQLにはNESTED TABLEというコレクション型がある
Oracle PL/SQLで利用できるコレクション型の一つがNESTED TABLEです。日本語のOracle資料では「ネストした表」や「ネスト表」と表現されることがあります。
PL/SQLブロック内では、TYPE 型名 IS TABLE OF 要素型;という形でネステッド・テーブル型を宣言できます。
例えば整数を複数格納する型なら、TYPE number_list IS TABLE OF NUMBER;と定義できます。これにより、NUMBER型の値を複数保持するコレクションとして利用できます。
NESTED TABLEの基本的な書き方
簡単な例として、複数の点数を保持するNESTED TABLEを作る場合を考えます。
DECLARE TYPE score_table IS TABLE OF NUMBER; scores score_table := score_table(80, 90, 75); BEGIN DBMS_OUTPUT.PUT_LINE(scores(1)); END;
この例では、score_tableというネステッド・テーブル型を定義し、80、90、75という3つの値で初期化しています。PL/SQLのネステッド・テーブルでは、通常最初の要素の添字は1から始まります。
そのためscores(1)は80、scores(2)は90、scores(3)は75を表します。
NESTED TABLEは要素数を増やせる
NESTED TABLEの特徴の一つは、VARRAYのような固定された最大要素数を宣言時に指定する必要がないことです。
初期化後にEXTENDメソッドを使えば、新しい要素を追加できます。
例えばscores.EXTEND; scores(scores.LAST) := 100;とすると、コレクションの末尾に要素を1つ増やして100を代入できます。
データ件数が実行時まで分からない場合や、処理中に要素を追加していきたい場合に使いやすいコレクションです。
DELETEを使って途中の要素を削除できる
NESTED TABLEでは、DELETEメソッドを使って特定の要素を削除できます。
例えばscores.DELETE(2);とすると、添字2の要素を削除できます。
ここで重要なのは、途中の要素を削除すると添字が必ず連続するとは限らない点です。例えば1、2、3のうち2を削除すると、1と3が存在し、2が存在しない状態になることがあります。
そのため、削除を行う可能性があるコレクションをループ処理するときは、単純に1 .. COUNTだけを使うより、FIRST、LAST、NEXTなどのコレクションメソッドを使うことがあります。
NESTED TABLEで使える主なコレクションメソッド
PL/SQLのコレクションには、要素数や添字を調べたり、要素を追加・削除したりするためのメソッドが用意されています。
| メソッド | 主な役割 |
|---|---|
COUNT |
現在存在する要素数を取得する |
FIRST |
最初に存在する添字を取得する |
LAST |
最後に存在する添字を取得する |
NEXT(n) |
nの次に存在する添字を取得する |
PRIOR(n) |
nの前に存在する添字を取得する |
EXISTS(n) |
指定した添字の要素が存在するか確認する |
EXTEND |
要素を追加する |
TRIM |
末尾の要素を削除する |
DELETE |
指定要素または複数要素を削除する |
これらを理解すると、NESTED TABLEを単なる配列のように使うだけでなく、可変長のデータ集合として柔軟に操作できるようになります。
Oracle PL/SQLのコレクション型は主に3種類
PL/SQLでよく扱うコレクションは、大きく分けて連想配列、NESTED TABLE、VARRAYの3種類があります。
| 種類 | 特徴 | 代表的な用途 |
|---|---|---|
| 連想配列 | 整数や文字列などをキーとして要素を管理できる | PL/SQL内部の一時データ、辞書的な処理 |
| NESTED TABLE | 可変長で要素を保持でき、途中の要素も削除可能 | 可変件数のデータ処理、SQLとの連携 |
| VARRAY | 要素数の上限を型定義時に指定する | 最大件数が明確な順序付きデータ |
それぞれ似ていますが、用途や制約が異なるため、データの性質に応じて選択する必要があります。
NESTED TABLEとVARRAYの違い
NESTED TABLEとVARRAYはどちらも複数の値を保持できますが、大きな違いは要素数の上限です。
VARRAYは型を作るときに、VARRAY(10)のように最大要素数を指定します。一方、NESTED TABLEではこのような最大件数を型定義で決めません。
例えば「曜日を最大7個保存する」「RGB値を決められた個数で管理する」といった最大件数が明確なデータならVARRAYが分かりやすい場合があります。
逆に、検索結果や処理対象IDの一覧など、何件になるか事前に固定できないデータではNESTED TABLEが適しています。
NESTED TABLEと連想配列の違い
連想配列は、以前はINDEX BY表とも呼ばれていたPL/SQLのコレクションです。NESTED TABLEとの大きな違いの一つが、添字の扱いです。
連想配列では整数だけでなく文字列をキーとして使用できる場合があります。例えば社員コードをキーとして名前を保持するといった使い方ができます。
NESTED TABLEは、SQLレベルで型を作成すればデータベース表の列として保存したり、SQLから扱ったりできる点が大きな特徴です。PL/SQL内部だけの一時的なキー・バリュー管理なら連想配列、SQLとの連携が必要ならNESTED TABLEを検討すると整理しやすくなります。
SQLレベルでNESTED TABLE型を定義することもできる
NESTED TABLEはPL/SQLブロック内だけで利用する方法に加えて、SQLのスキーマオブジェクトとして型を作成することもできます。
例えば次のような型を作れます。
CREATE TYPE phone_list AS TABLE OF VARCHAR2(30);
このようなSQLレベルのコレクション型は、テーブル定義の列型などとして利用できます。PL/SQLローカル型とは用途が異なるため、「どこから利用する必要があるか」を考えて型の定義場所を決めます。
テーブルの列としてNESTED TABLEを保存できる
SQLレベルで定義したNESTED TABLE型は、通常のリレーショナル表の列に指定できます。例えば、1人の顧客が複数の電話番号を持つケースを考えられます。
CREATE TYPE phone_list AS TABLE OF VARCHAR2(30);で型を定義したあと、顧客テーブルの電話番号列にこの型を使用できます。
ネステッド・テーブル列を持つ表を作成する際には、そのコレクション要素を保存するためのストレージ表も指定します。概念的には親となる1行に対して複数要素を関連付ける形です。
ただし、実務では通常の子テーブルとして正規化した設計のほうが検索・更新・制約管理を行いやすいケースも多いため、「複数値を持たせたいから必ずNESTED TABLEを使う」と考えるのではなく、データモデル全体から判断することが重要です。
TABLE演算子を使うとコレクションを行として扱える
SQLで扱えるNESTED TABLEでは、TABLE()演算子によってコレクションを行集合のように参照できます。
例えばコレクションが格納された列を展開して、各要素を個別の行としてSELECTするといった処理が可能です。
この点が、単にPL/SQLプログラム内で値を一時保持するだけの配列的な用途とは異なるNESTED TABLEの特徴です。SQLとPL/SQLの双方で複数値を受け渡したい場面では重要な仕組みになります。
BULK COLLECTと組み合わせることもある
PL/SQLでは、SELECT結果を複数件まとめてコレクションへ取得するためにBULK COLLECTを使用できます。NESTED TABLEはその格納先として利用されることがあります。
例えば複数の社員IDをまとめて取得する場合、概念的にはSELECT employee_id BULK COLLECT INTO ids FROM employees;のように書けます。
1行ずつ処理するのではなく複数行をまとめてPL/SQLへ取得することで、SQLエンジンとPL/SQLエンジン間の切り替え回数を減らし、処理効率を改善できるケースがあります。
ただし大量データを一度に取得するとPGAメモリを多く消費する可能性があるため、データ量が大きい場合はLIMITを使った分割取得なども検討します。
NESTED TABLEは「表の中に普通の表がそのまま入る」という意味ではない
「ネストした表」という名前から、通常のデータベース表がそのまま別の表の内部へ格納されるイメージを持つことがありますが、少し異なります。
NESTED TABLEはOracleが提供するコレクション型であり、一つの値として複数要素を持つための仕組みです。PL/SQLでは可変長のコレクションとして扱い、SQLスキーマ型なら表の列として保存することもできます。
したがって、一般的なリレーショナルデータベースにおける「親テーブルと子テーブル」の概念と完全に同じものではありません。名称ではなく、コレクション型の一種として理解すると混乱しにくくなります。
NESTED TABLEを選ぶべき場面
NESTED TABLEは、処理対象となる要素数が実行時に変わる場合や、PL/SQLとSQLの間で複数の値をまとめて扱いたい場合に候補になります。
例えば、検索したIDの一覧をPL/SQLで処理する、一括処理対象のデータを保持する、SQLレベルのコレクション型として関数との間で複数値を受け渡す、といった用途があります。
一方、単純な親子関係の業務データを永続保存するだけなら、一般的な親テーブル・子テーブル設計のほうが扱いやすい場合があります。また、最大要素数が明確ならVARRAY、文字列キーによる高速な一時参照が目的なら連想配列が適する場合があります。
まとめ:NESTED TABLEはOracle PL/SQLの代表的なコレクション型
Oracle PL/SQLにはNESTED TABLEというコレクション型があります。基本的にはTYPE 型名 IS TABLE OF 要素型;という形で定義し、複数の値を可変長で保持できます。
NESTED TABLEはEXTENDで要素を増やしたり、DELETEで要素を削除したりできるほか、COUNT、FIRST、LAST、NEXTなどのコレクションメソッドも利用できます。
Oracle PL/SQLの代表的なコレクションは、連想配列、NESTED TABLE、VARRAYの3種類です。NESTED TABLEは要素数を固定せず扱えること、SQLレベルで型を定義すればSQLとの連携やデータベースへの格納が可能であることが特徴です。
「NESTED TABLE=表が物理的に別の表へそのまま入るもの」と覚えるのではなく、複数要素をまとめて扱える可変長のコレクション型として理解すると、PL/SQLのコレクション全体を整理しやすくなります。


コメント