Oracle PL/SQLコレクション: VARRAY、ネスト、表による索引付け

コレクションとは?

コレクションは、特定のデータ型の要素を順序付けたグループです。単純なデータ型または複雑なデータ型 (ユーザー定義型やレコード型など) のコレクションにすることができます。

コレクション内の各要素は、と呼ばれる用語によって識別されます。 "添字。" コレクション内の各項目には、一意の添字が割り当てられます。 そのコレクション内のデータは、その一意の添え字を参照することによって操作またはフェッチできます。

コレクションは、同じ種類の大きなデータを処理または操作する必要がある場合に最も役立ちます。コレクションは、「BULK」オプションを使用して全体として設定および操作できます。 Oracle.

コレクションは、以下に示すように、構造、添え字、ストレージに基づいて分類されます。

  • テーブルによるインデックス (連想配列とも呼ばれます)
  • ネストされたテーブル
  • 変数

コレクション内のデータはいつでも、コレクション名、添え字、フィールド/列名という XNUMX つの用語で参照できます。 ( )。 ”。 これらの上記のコレクション カテゴリについては、以下のセクションでさらに詳しく学習します。

変数

Varray は、配列のサイズが固定されているコレクション メソッドです。配列のサイズは、固定値を超えることはできません。Varray の添え字は数値です。以下は、Varray の属性です。

  • 上限サイズは固定です
  • 添字「1」から順に入力されます。
  • このコレクション型は常に密です。つまり、配列要素を削除することはできません。 VARRAY は全体として削除することも、末尾からトリミングすることもできます。
  • 本質的に常に密度が高いため、柔軟性が非常に低くなります。
  • 配列サイズがわかっている場合に使用し、すべての配列要素に対して同様のアクティビティを実行する方が適切です。
  • 添字とシーケンスは常に安定しています。つまり、コレクションの添字とカウントは常に同じです。
  • プログラムで使用する前に初期化する必要があります。初期化されていないコレクションに対する操作 (EXISTS 操作を除く) はエラーをスローします。
  • これはデータベース オブジェクトとして作成でき、データベース全体またはサブプログラム内で表示され、そのサブプログラム内でのみ使用できます。

以下の図は、Varray (dense) のメモリ割り当てを図的に説明します。

添字 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」から順に入力されます。
  • このコレクション タイプは両方のタイプになります。 密でまばらつまり、コレクションを密として作成でき、また個々の配列要素をランダムに削除して、それを疎にすることもできます。
  • これにより、配列要素の削除に関してより柔軟な対応が可能になります。
  • これはシステムが生成したデータベース テーブルに保存され、選択クエリで値をフェッチするために使用できます。
  • 添字とシーケンスは安定していません。つまり、添字と配列要素の数は変化する可能性があります。
  • プログラムで使用する前に初期化する必要があります。初期化されていないコレクションに対する操作 (EXISTS 操作を除く) はエラーをスローします。
  • これはデータベース オブジェクトとして作成でき、データベース全体またはサブプログラム内で表示され、そのサブプログラム内でのみ使用できます。

以下の図は、ネストしたテーブル (密および疎) のメモリ割り当てを図的に説明します。 黒色の要素空間は、コレクション内の空の要素、つまりスパースを示します。

添字 1 2 3 4 5 6 7
値 (密) Xyz Dfv スデ Cxs Vbc ヌー クウェ
値(スパース) クウェ ASD AFG ASD WER

ネストしたテーブルの構文:

TYPE <tvpe name> IS TABLE OF <DATA TYPE>;
  • 上記の構文では、type_name は 'DATA_TYPE' 型のネストされたテーブル コレクションとして宣言されています。データ型は単純型または複合型のいずれかです。

テーブルごとのインデックス

インデックス バイ テーブルは、配列のサイズが固定されていないコレクションです。他のコレクション タイプとは異なり、インデックス バイ テーブル コレクションでは、ユーザーが定義した添字で構成できます。以下は、インデックス バイ テーブルの属性です。

  • 添字には整数または文字列を使用できます。 コレクションの作成時に、添え字のタイプを指定する必要があります。
  • これらのコレクションは順番に保存されません。
  • それらは常に本質的にまばらです。
  • 配列のサイズは固定されていません。
  • データベース列に格納することはできません。 これらは、その特定のセッションのプログラムで作成および使用されます。
  • これらにより、添え字の維持に関してより柔軟な対応が可能になります。
  • 添え字は負の添え字シーケンスにすることもできます。
  • これらは、同じサブプログラム内でコレクションを初期化して使用できる、比較的小さな集合値に使用するのがより適切です。
  • 使用を開始する前に初期化する必要はありません。
  • データベース オブジェクトとして作成することはできません。 サブプログラム内でのみ作成でき、そのサブプログラム内でのみ使用できます。
  • BULK COLLECT は、コレクション内のレコードごとに添字を明示的に指定する必要があるため、このコレクション タイプでは使用できません。

以下の図は、ネストテーブル(スパース)のメモリ割り当てを図式的に説明したものです。 黒色の要素空間は、コレクション内の空の要素、つまりスパースを示します。

添字(varchar) 最初 SECOND THIRD 第4 FIFTH SIXTH XNUMX番目
値(スパース) クウェ ASD AFG ASD WER

Index-by-Table の構文

TYPE <type_name> IS TABLE OF <DATA_TYPE> INDEX BY VARCHAR2 (10);
  • 上記の構文では、type_name は 'DATA_TYPE' 型のインデックス バイ テーブル コレクションとして宣言されています。データ型は単純型または複合型のいずれかです。subsciprt/index 変数は最大サイズが 2 の VARCHAR10 型として指定されます。

コレクションのコンストラクターと初期化の概念

コンストラクタは、オブジェクトまたはコレクションと同じ名前を持つ、Oracle によって提供される組み込み関数です。セッションでオブジェクトまたはコレクションが初めて参照されるたびに、最初に実行されます。以下は、コレクション コンテキストにおけるコンストラクタの重要な詳細です。

  • コレクションの場合、これらのコンストラクターを明示的に呼び出して初期化する必要があります。
  • Varray 表とネストした表は両方とも、プログラムで参照される前に、これらのコンストラクターを通じて初期化する必要があります。
  • コンストラクターはコレクション (Varray を除く) のメモリ割り当てを暗黙的に拡張するため、コンストラクターは変数をコレクションに割り当てることもできます。
  • コンストラクターを通じてコレクションに値を代入しても、コレクションがスパースになることはありません。

収集方法

Oracle コレクションを操作および操作するための多くの関数を提供します。これらの関数は、プログラムでコレクションのさまざまな属性を決定および変更するのに非常に役立ちます。次の表に、さまざまな関数とその説明を示します。

方法 Description 構文
存在します (n) このメソッドはブール値の結果を返します。 n の場合、「TRUE」を返します。th 要素がそのコレクションに存在する場合、それ以外の場合は FALSE が返されます。 初期化されていないコレクションでは EXISTS 関数のみを使用できます .EXISTS(要素の位置)
COUNT コレクション内に存在する要素の総数を示します。 。カウント
LIMIT コレクションの最大サイズを返します。 Varray の場合、定義されている固定サイズが返されます。 ネストされたテーブルとインデックスによるテーブルの場合は、NULL が返されます。 .LIMIT
最初 コレクションの最初のインデックス変数(添え字)の値を返します。 。初め
LAST コレクションの最後のインデックス変数(添字)の値を返します。 。最後
前 (n) n のコレクション内の先行インデックス変数を返します。th 要素。 先行するインデックス値がない場合は NULL が返されます .PRIOR(n)
次へ (n) n のコレクション内の成功したインデックス変数を返します。th 要素。 成功したインデックス値がない場合は NULL が返されます .NEXT(n)
延長 最後にコレクション内の XNUMX つの要素を拡張します 。伸ばす
拡張 (n) コレクションの最後にある n 個の要素を拡張します .EXTEND(n)
拡張 (n,i) i の n 個のコピーを拡張しますth コレクションの最後にある要素 .EXTEND(n,i)
TRIM コレクションの末尾から XNUMX つの要素を削除します 。トリム
トリム (n) コレクションの末尾から n 個の要素を削除します .TRIM(n)
DELETE コレクションからすべての要素を削除します。 コレクションを空にします 。消去
削除 (n) コレクションから n 番目の要素を削除します。 n の場合th 要素が NULL の場合、これは何も行いません .DELETE(n)
削除 (m,n) m範囲の要素を削除します。th nにth コレクションの中で .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;
/

コードの説明:

  • コード行 2 ~ 8: レコードタイプ 「emp_det」は、データ型 NUMBER、VARCHAR2、NUMBER、NUMBER の列 emp_no、emp_name、salary、manager で宣言されています。
  • コード行 9: レコードタイプ要素「emp_det」のコレクション「emp_det_tbl」を作成しています
  • コード行 10: 変数「guru99_emp_rec」を「emp_det_tbl」型として宣言し、null コンストラクターで初期化します。
  • コード行 12 ~ 15: サンプル データを 'emp' テーブルに挿入します。
  • コード行 16: 挿入トランザクションをコミットしています。
  • コード行 17: 「emp」テーブルからレコードをフェッチし、コマンド「BULK COLLECT」を使用してコレクション変数に一括でデータを設定します。 これで、変数「guru99_emp_rec」には、テーブル「emp」に存在するすべてのレコードが含まれます。
  • コード行 19 ~ 26: コレクション内のすべてのレコードを XNUMX つずつ出力するために使用する 'FOR' ループを設定します。 収集方法 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
----------------------------------------------