Oracle PL/SQLコレクション: VARRAY、ネスト、表による索引付け
⚡ スマートサマリー
PL/SQLコレクションは、同じデータ型の要素を順序付けしてグループ化したもので、各要素には添え字でアクセスできます。Varray、ネストされたテーブル、インデックス付きテーブルの3種類があり、サイズが固定されているかどうか、添え字の動作方法、データベースに格納できるかどうかが異なります。
コレクションとは何ですか?
コレクションとは、特定のデータ型の要素を順序付けしてまとめたものです。コレクションは、単純なデータ型のコレクションである場合もあれば、ユーザー定義型やレコード型などの複雑なデータ型のコレクションである場合もあります。
コレクションでは、各要素は、 "添字。" 各項目には固有の添え字が割り当てられ、その固有の添え字を参照することでデータを操作したり取得したりすることができる。
コレクションは、同じタイプの大量のデータを処理または操作する必要がある場合に最も役立ちます。コレクションは、「BULK」オプションを使用して全体としてデータを格納および操作できます。 Oracle.
コレクションは、以下に示すように、構造、添え字、および格納方法に基づいて分類されます。
- インデックス付きテーブル(連想配列とも呼ばれる)
- ネストされたテーブル
- 変数
コレクション内のデータは、いつでもコレクション名、添え字、フィールド名または列名の 3 つの用語で参照できます。 ( )これらのコレクションカテゴリについては、以下のセクションで説明します。
コレクションの種類の概要
これら3種類のコレクションタイプは、それぞれ異なるトレードオフを持っています。以下の表では、それぞれのタイプを並べて比較した後、詳細に解説します。
| 側面 | ヴァレイ | ネストされたテーブル | 表による索引 |
|---|---|---|---|
| サイズ | 固定上限値 | 制限なし | 制限なし |
| 添字 | 数値の | 数値の | 整数または文字列 |
| 密度 | 常に密度が高い | 密集しているか疎らか | 常にまばら |
| データベースに保存されています | はい | はい | いいえ |
| 初期化が必要です | はい | はい | いいえ |
変数
Varrayは、配列のサイズが固定されており、それを超えることができないコレクションです。Varrayの添え字は数値です。Varrayの属性は次のとおりです。
- 上限サイズは固定されています。
- 添え字「1」から順にデータが格納されます。
- このコレクション型は常に密な配列であり、個々の配列要素を削除することはできません。Varrayは全体として削除するか、末尾から一部を削除することができます。
- 常に密度が高いため、柔軟性が非常に低い。
- 配列のサイズが既知であり、すべての要素に対して同様の処理が行われる場合に、この方法はより適切です。
- コレクションの添え字と要素数は常に安定している。
- 使用する前に初期化する必要があります。初期化されていないコレクションに対して、EXISTS以外の操作を行うとエラーが発生します。
- これは、データベース全体で参照可能なデータベースオブジェクトとして作成することも、サブルーチン内でのみ使用されるように作成することもできます。
下の図は、Varray(密配列)のメモリ割り当てについて説明しています。
| 添字 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 値 | Xyz | Dfv | スデ | Cxs | Vbc | ヌー | クウェ |
VARRAY の構文:
TYPE <type_name> IS VARRAY (<SIZE>) OF <DATA_TYPE>;
- 上記の構文では、type_name は指定されたサイズ制限内で 'DATA_TYPE' 型の VARRAY として宣言されています。データ型は単純型でも複雑型でも構いません。
ネストされたテーブル
ネストされたテーブルは、配列のサイズが固定されていないコレクションです。数値の添え字型を持ちます。ネストされたテーブル型の詳細については、以下をご覧ください。
- ネストされたテーブルには、サイズの上限はありません。
- 上限が固定されていないため、メモリを使用するたびに「EXTEND」キーワードを使用してメモリを拡張する必要があります。
- 添え字「1」から順にデータが格納されます。
- このコレクションタイプは 密でまばら; 密なデータとして作成することも、個々の要素をランダムに削除して疎なデータにすることもできます。
- 配列要素の削除において、より柔軟な対応が可能になります。
- これはシステムによって生成されたデータベーステーブルに格納され、SELECTクエリで値を取得するために使用できます。
- 添え字と桁数は異なる場合があります。
- 使用する前に初期化する必要があります。初期化されていないコレクションに対して、EXISTS以外の操作を行うとエラーが発生します。
- これは、データベース全体で参照可能なデータベースオブジェクトとして作成することも、サブルーチン内でのみ使用されるように作成することもできます。
下図は、ネストされたテーブル(密なテーブルと疎なテーブル)のメモリ割り当てについて説明しています。空の要素スペースは疎な要素を表します。
| 添字 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 値 (密) | Xyz | Dfv | スデ | Cxs | Vbc | ヌー | クウェ |
| 値(疎行列) | クウェ | ASD | AFG | ASD | WER |
ネストしたテーブルの構文:
TYPE <type_name> IS TABLE OF <DATA_TYPE>;
- 上記の構文では、type_name は型 'DATA_TYPE' のネストされたテーブルコレクションとして宣言されています。データ型は、単純型でも複合型でも構いません。
表による索引
インデックス付きテーブルは、配列サイズが固定されていないコレクションです。他のコレクションタイプとは異なり、インデックス付きテーブルの添え字はユーザーが定義できます。インデックス付きテーブルの属性は次のとおりです。
- 添え字は整数または文字列を指定できます。コレクションを作成する際に、添え字の型を指定する必要があります。
- これらのコレクションは順番に保存されません。
- それらは常に本質的にまばらです。
- 配列のサイズは固定されていません。
- これらはデータベースの列に保存することはできません。特定のセッション内で作成され、使用されます。
- それらは添え字を維持する上でより柔軟性を提供する。
- 添え字は負の数列でも構いません。
- これらは、同じサブプログラム内で使用される比較的小さなコレクション値に適しています。
- 使用前に初期化する必要はありません。
- これらはデータベースオブジェクトとして作成することはできません。サブルーチン内でのみ作成されます。
- このコレクションタイプでは、各レコードに添え字を明示的に指定する必要があるため、BULK COLLECTは使用できません。
下図は、インデックス付きテーブル(疎行列)のメモリ割り当てについて説明しています。空の要素スペースは、疎行列要素を表します。
| 添字(varchar) | 最初 | SECOND | THIRD | 第4 | FIFTH | SIXTH | XNUMX番目 |
| 値(疎行列) | クウェ | ASD | AFG | ASD | WER |
テーブルによるインデックスの構文:
TYPE <type_name> IS TABLE OF <DATA_TYPE> INDEX BY VARCHAR2 (10);
- 上記の構文では、type_nameは型「DATA_TYPE」のインデックス付きテーブルコレクションとして宣言されています。添え字変数は、最大サイズ10のVARCHAR2型として指定されています。
コレクションのコンストラクターと初期化の概念
コンストラクタは、によって提供される組み込み関数です。 Oracle オブジェクトまたはコレクションと同じ名前を持つコンストラクタ。セッション内でオブジェクトまたはコレクションが初めて参照されるたびに、最初に実行されます。コレクションコンテキストにおけるコンストラクタの重要な詳細:
- コレクションの場合、コレクションを初期化するには、これらのコンストラクタを明示的に呼び出す必要があります。
- Varrayとネストされたテーブルはどちらも、プログラム内で参照する前に、これらのコンストラクタを使用して初期化する必要があります。
- コンストラクタは、コレクション(Varrayを除く)のメモリ割り当てを暗黙的に拡張するため、コレクションに変数を割り当てることもできます。
- コンストラクタを介して値を割り当てると、コレクションが疎になることはありません。
収集方法
Oracle コレクションを操作・管理するための多くの関数を提供します。これらの関数は、コレクションのさまざまな属性を決定および変更します。以下の表に、各関数とその説明を示します。
| 方法 | 詳細説明 | 構文 |
|---|---|---|
| 存在します (n) | ブール値を返します。n番目の要素が存在する場合はTRUE、存在しない場合はFALSEを返します。初期化されていないコレクションに対しては、EXISTSのみを使用できます。 | .EXISTS(要素の位置) |
| COUNT | コレクションに含まれる要素の総数を返します。 | 。カウント |
| LIMIT | コレクションの最大サイズを返します。Varray の場合は固定サイズを返し、ネストされたテーブルおよびインデックス付きテーブルの場合は NULL を返します。 | .LIMIT |
| 最初 | コレクションの最初の添え字の値を返します。 | 。初め |
| LAST | コレクションの最後の添え字の値を返します。 | 。最後 |
| 前 (n) | n番目の要素の直前の添え字を返します。添え字がない場合はNULLを返します。 | .PRIOR(n) |
| 次へ (n) | n番目の要素の次の添え字を返します。添え字がない場合はNULLを返します。 | .NEXT(n) |
| 延長 | コレクションの末尾にある要素を1つ拡張します。 | 。伸ばす |
| 拡張 (n) | コレクションの末尾にn個の要素を追加します。 | .EXTEND(n) |
| 拡張 (n,i) | コレクションの末尾にあるi番目の要素のn個のコピーを拡張します。 | .EXTEND(n,i) |
| TRIM | コレクションの末尾から要素を1つ削除します。 | 。トリム |
| トリム (n) | コレクションの末尾からn個の要素を削除します。 | .TRIM(n) |
| DELETE | コレクションからすべての要素を削除し、コレクションを空にします。 | 。消去 |
| 削除 (n) | n番目の要素を削除します。n番目の要素がNULLの場合は、何も行いません。 | .DELETE(n) |
| 削除 (m,n) | コレクション内のm番目からn番目までの範囲の要素を削除します。 | .DELETE(m,n) |
例1:サブプログラムレベルでのレコードタイプ
この例では、' を使用してコレクションにデータを入力する方法を示します。一括収集そして、収集データを参照する方法。
DECLARE TYPE emp_det IS RECORD ( EMP_NO NUMBER, EMP_NAME VARCHAR2(150), MANAGER NUMBER, SALARY NUMBER ); TYPE emp_det_tbl IS TABLE OF emp_det; guru99_emp_rec emp_det_tbl:= emp_det_tbl(); BEGIN INSERT INTO emp (emp_no,emp_name, salary, manager) VALUES (1000,'AAA',25000,1000); INSERT INTO emp (emp_no,emp_name, salary, manager) VALUES (1001,'XXX',10000,1000); INSERT INTO emp (emp_no, emp_name, salary, manager) VALUES (1002,'YYY',15000,1000); INSERT INTO emp (emp_no,emp_name,salary, manager) VALUES (1003,'ZZZ',7500,1000); COMMIT; SELECT emp_no,emp_name,manager,salary BULK COLLECT INTO guru99_emp_rec FROM emp; dbms_output.put_line ('Employee Detail'); FOR i IN guru99_emp_rec.FIRST..guru99_emp_rec.LAST LOOP dbms_output.put_line ('Employee Number: '||guru99_emp_rec(i).emp_no); dbms_output.put_line ('Employee Name: '||guru99_emp_rec(i).emp_name); dbms_output.put_line ('Employee Salary:'|| guru99_emp_rec(i).salary); dbms_output.put_line('Employee Manager Number:'||guru99_emp_rec(i).manager); dbms_output.put_line('--------------------------------'); END LOOP; END; /
Code 説明
- Code 2行目~8行目: レコードタイプ 'emp_det' は、データ型が NUMBER、VARCHAR2、NUMBER、および NUMBER である emp_no、emp_name、manager、および salary の列で宣言されています。
- Code 9行目: レコードタイプ要素「emp_det」のコレクション「emp_det_tbl」を作成しています。
- Code 10行目: 変数「guru99_emp_rec」を「emp_det_tbl」型として宣言し、nullコンストラクタで初期化します。
- Code 12行目~15行目: サンプル データを 'emp' テーブルに挿入します。
- Code 16行目: 挿入トランザクションをコミットしています。
- Code 17行目: 「emp」テーブルからレコードを取得し、「BULK COLLECT」を使用してコレクション変数に一括でデータを格納します。これで、変数「guru99_emp_rec」には、「emp」テーブルに存在するすべてのレコードが格納されました。
- Code 19行目~26行目: 'FOR' ループを設定して、コレクション内のすべてのレコードを 1 つずつ出力します。コレクション メソッド FIRST と LAST は、コレクションの下限と上限として使用されます。 ループ.
出力: 上記のコードを実行すると、以下の出力が得られます。
Employee Detail Employee Number: 1000 Employee Name: AAA Employee Salary: 25000 Employee Manager Number: 1000 ---------------------------------------------- Employee Number: 1001 Employee Name: XXX Employee Salary: 10000 Employee Manager Number: 1000 ---------------------------------------------- Employee Number: 1002 Employee Name: YYY Employee Salary: 15000 Employee Manager Number: 1000 ---------------------------------------------- Employee Number: 1003 Employee Name: ZZZ Employee Salary: 7500 Employee Manager Number: 1000 ----------------------------------------------


