web-dev-qa-db-ja.com

OracleでさまざまなタイプのPL / SQLコレクションを使用する目的

Oracleでコレクションを使用する主な目的は何ですか?

  1. テーブルによるインデックス

  2. ネストされたテーブル

  3. 可変サイズ配列

上記のコレクションの違いを教えてください。

4
Madhav

ネストされたテーブルから始めましょう。これらはコレクションの最も一般的な形式であるため、比較の有用な基礎を表します。

ネストされたテーブルは、何かの複数のインスタンスを保持できる変数であり、多くの場合、データベーステーブルのレコードです。それらは次のように宣言される可能性があります。

type emp_nt is table of emp%rowtype;
emp_rec_nt emp_nt;

同じことをしたいデータの複数のインスタンスを保存したいときはいつでも便利です。典型的な例は、BULKCOLLECTを使用して複数のレコードを保存することです。

select * 
bulk collect into emp_rec_nt
from employees;

これにより、ループできるデータのソースが得られます。重要なのは、カーソルではできないことである、最後または最初にスキップすることでさえ、前方だけでなく後方にもナビゲートできることです。ネストされた表は、PL/SQLレコードやユーザー定義型などのコンポジットを含む、任意のデータ型のコレクションにすることができます。

Index Byテーブルは、(ドキュメントのように)連想配列と呼ばれる方が適切です。これらは、インデックス付きの単一属性の単純なコレクションです。ネストされたテーブルにもインデックスがありますが、それらのインデックスは単なる行数です。連想配列を使用すると、インデックスは意味のあるものになります。つまり、データ値から取得されます。したがって、後で使用するためにデータ値をキャッシュするのに役立ちます。インデックスは数値、または(9iR2以降)非常に便利な文字列にすることができます。たとえば、これは従業員IDによってインデックス付けされた給与の連想配列です。

type emp_sal_aa is table of emp.sql%type
     index by emp.empno%type;
l_emp_sales emp_sal_aa;

INDEX BY BINARY_INTEGERを使用してその配列を宣言することもできますが、代わりに%TYPE構文を使用する方が明確です(自己文書化コード)。その配列の要素は、インデックス値(この場合はEMPNO)で識別できます。

l_emp_sals(l_emp_no) := l_emp_sal;

参照テーブルまたは同様のルックアップ値をキャッシュする以外に、連想配列のユースケースは多くありません。

変数配列は、要素数に事前定義された制限があるネストされたテーブルです。したがって、おそらくその名前は誤解を招く可能性があります。実際には固定配列です。ネストされたテーブルでは実行できないVArrayで実行できることはほとんどありません(要素の数を制限することを除いて、それを実行することは非常にまれです)。それらは次のように宣言されます:

type emp_va is varray(14) of emp%rowtype;
emp_rec_va emp_va;

バルクコレクトを使用してVArrayにデータを入力できます...

select * 
bulk collect into emp_rec_va
from employees;

ただし、クエリがVArrayの宣言で指定された要素の数を最大返すことを確認する必要があります。それ以外の場合、SELECTはORA-22165を投げます。

変数配列の既知の使用例はありません。少し厳しいですが、ほとんどの場合、代わりにネストされたテーブルを使用します。ネストされたテーブルに対するVArrayの大きな利点の1つは、要素の順序が保証されることです。したがって、要素を挿入したのと同じ順序で取り出す必要がある場合は、VArrayを使用してください。

PL/SQLのドキュメントでは、章全体をコレクションに当てています。 詳細

21
APC

PL/SQLは、次のコレクション・タイプを提供します。

連想配列は、インデックスバイテーブルとも呼ばれ、添え字値に任意の数値と文字列を使用して要素を検索できます。これらは、他のプログラミング言語のハッシュテーブルに似ています。

ネストされたテーブルは、任意の数の要素を保持します。添え字として連番を使用します。同等のSQLタイプを定義して、ネストされたテーブルをデータベーステーブルに格納し、SQLを介して操作できるようにすることができます。

Varray(可変サイズ配列の略)は、固定数の要素を保持します(ただし、実行時に要素の数を変更できます)。添え字として連番を使用します。同等のSQLタイプを定義して、VARRAYをデータベーステーブルに格納できるようにすることができます。これらはSQLを介して格納および取得できますが、ネストされたテーブルよりも柔軟性が低くなります。

1.ネストされたテーブルと連想配列の選択:-

ネストされたテーブルと連想配列(以前はインデックスバイテーブルと呼ばれていました)はどちらも同様の添え字表記を使用しますが、永続性とパラメーターの受け渡しのしやすさに関しては異なる特性を持っています。

ネストされたテーブルはデータベース列に格納できますが、連想配列は格納できません。ネストされたテーブルは、通常は単一列のテーブルをより大きなテーブルと結合するSQL操作を簡素化できます。

連想配列は、プロシージャが呼び出されるかパッケージが初期化されるたびにコレクションをメモリ内に構築できる比較的小さなルックアップテーブルに適しています。サイズに制限がないため、事前にボリュームが不明な情報を収集するのに適しています。連想配列の添え字は負の値、非順次文字、数値の代わりに文字列値を使用できるため、インデックス値はより柔軟です。

PL/SQLは、ホスト配列とテンキー値を使用する連想配列の間で自動的に変換します。データベースサーバーとの間でコレクションをやり取りする最も効率的な方法は、連想配列にデータ値を設定し、それらの連想配列をバルク構造(FORALLステートメントまたはBULK COLLECT句)で使用することです。

2.ネストされたテーブルとVarrayのどちらを選択するか:-

Varrayは、次の場合に適しています。

要素の数は事前にわかっています。

通常、要素はすべて順番にアクセスされます。

データベースに保存されると、VARRAYは順序と添え字を保持します。

各VARRAYは、列であるテーブル内(VARRAYが4KB未満の場合)またはテーブル外で同じテーブルスペース内(VARRAYが4KBより大きい場合)のいずれかで、単一のオブジェクトとして格納されます。 VARRAYのすべての要素を同時に更新または取得する必要があります。これは、すべての要素に対して一度に何らかの操作を実行する場合に最も適切です。ただし、この方法で多数の要素を格納および取得することは実用的ではない場合があります。

ネストされたテーブルは、次の場合に適しています。

インデックス値は連続していません。

インデックス値の設定数はありません。ただし、上限があります。

一部の要素を削除または更新する必要がありますが、すべての要素を一度に削除する必要はありません。

通常は、メインテーブルの各行に複数のエントリを含む個別のルックアップテーブルを作成し、結合クエリを介してアクセスします。

ネストされたテーブルはスパースである可能性があります。アイテムを最後から削除するだけでなく、任意の要素を削除できます。

ネストされたテーブルデータは、ネストされたテーブルに関連付けられたシステム生成のデータベーステーブルである別のストアテーブルに格納されます。ネストされたテーブルにアクセスすると、データベースがテーブルを結合します。これにより、ネストされたテーブルは、コレクションの一部の要素にのみ影響するクエリと更新に適しています。

ネストされたテーブルはデータベースに保存され、データベースから取得されるため、ネストされたテーブルの順序と添え字がデータベースに保持されないため、その順序と添え字が安定しているとは限りません。

5
shivaranjani

Uはリンクを使用できます

ネストされた配列と連想配列の違いは何ですか?

または単にそれを読んでください。

ネストされたテーブルは、n個の要素の単なる配列です。

declare
  type nested_table_of_integer is table of integer;
  v_my_nested_table nested_table_of_integer;
begin
  v_my_nested_table := nested_table_of_integer(); -- initialize
  v_my_nested_table.extend(10); -- add 10 elements
  v_my_nested_table(1) := 100;
  v_my_nested_table(11) := 1000; -- ORA-06533: Subscript beyond count
end;

ネストされたテーブルは、次のように初期化する必要があります。最初は要素がゼロです。要素を追加するには、EXTENDを使用します。このネストされたテーブルには10個の要素があります。インデックスは1から10です。要素1の値は100です。その他の要素の値はnullです。存在しない要素、たとえば11番目の要素にアクセスすると、エラーが発生します。

一方、連想配列は、名前と値のペアの配列です。命名に番号(通常はpls_integer)を使用しましょう:

declare
      type associative_array_of_integer is table of integer index by pls_integer;
      v_my_associative_array associative_array_of_integer;
    begin
      v_my_associative_array(1) := 100;
      v_my_associative_array(11) := 1000;
      v_my_associative_array(12) := v_my_associative_array(2); -- ORA-01403: no data found

end;

連想配列は初期化する必要がありません。空で、データが入力されます。ここでは、1という要素を値100に関連付け、名前11の要素を値1000に関連付けます。したがって、配列には2つの要素があります。配列にない名前にアクセスしようとすると、データが見つからないという例外が発生します。

名前に文字列を使用することもできます。

declare
  type associative_array_of_integer is table of integer index by varchar2(100);
  v_my_associative_array associative_array_of_integer;
begin
  v_my_associative_array('age father') := 39;
  v_my_associative_array('age mother') := 32;
  v_my_associative_array('age daughter') := 11;
end;

両方のコレクションを使用してテーブルデータを取得できますが、使用方法は異なります。ネストされたテーブルにはカウントがあり、1からカウントにループしてその要素にアクセスできます。

declare
  type nested_table_of_integer is table of integer;
  v_my_nested_table nested_table_of_integer;
begin
  v_my_nested_table := nested_table_of_integer(); -- initialize
  select table_name bulk collect into v_my_nested_table from user_tables;
  for i in 1 .. v_my_nested_table.count loop
    dbms_output.put_line(v_my_nested_table(i));
  end loop;
end;

ただし、連想配列は、FIRSTとNEXTを使用して、最初のインデックスであるものから次、次、次へと読み取る必要があります。

declare
  type associative_array_of_integer is table of integer index by pls_integer;
  v_my_associative_array associative_array_of_integer;
  i integer;
 begin
  select table_name bulk collect into v_my_associative_array from user_tables;
  i := v_my_associative_array.first;
  while i is not null loop
    dbms_output.put_line(v_my_associative_array(i));
    i := v_my_associative_array.next(i);
  end loop;
end;

ここでの「名前」はたまたま1、2、3などであり(したがってバルクコレクションによって与えられます)、たとえばv_my_associative_array(1)にアクセスできます。ただし、プログラムの後半では、配列で削除操作が行われた後、ギャップが生じる可能性があるため、1という名前の要素が存在するかどうか、および要素4の前の要素がたまたま要素3であるかどうかはわかりません。一括収集と同様です。要素の「名前」は、実際には使用しないという意味ではなく、図のようにチェーンを通過します。

2
Puneet Kushwah

コレクションは、すべて同じタイプの要素の順序付けられたグループです。各要素は、コレクション内での位置を表す一意の添え字で識別されます

PL/SQLは3つのコレクションタイプを提供します-

インデックスバイテーブルまたは連想配列ネストされたテーブル可変サイズ配列またはVarray

0
Bharat Negi

テーブルによるインデックスは、複数のデータ項目を格納するために使用されるユーザー定義のデータ型です。基本的に、これらのテーブルは制約のないテーブルです。値フィールドとキーフィールドの2つの部分からなるテーブルによるインデックス。値フィールドでは、Oracleサーバーは実際のデータを格納しますが、キーフィールドと同様にOracleサーバーはインデックスを格納します。そのため、「キー値」のペアを持つテーブルごとのインデックスとインデックスはデフォルトで整数であり、これらのインデックスは負の数から正の数の間にあります。このインデックスフィールドは主キーのように動作し、重複する値を受け入れません。これらのテーブルはメモリ領域に格納されるため、通常、テーブルによるインデックスはパフォーマンスやアプリケーションを改善するために使用されます。そのため、これらのテーブルはメモリテーブルとも呼ばれます。通常、アプリケーションのパフォーマンスを向上させるために、これらのテーブルインデックスは「binary-integer」データ型を使用しているため、2段階のプロセスで作成しています。最初に型を作成し、次にその型の変数を作成するだけです。

構文:-

ステップ1:-タイプtypenameは、binary_integerによるデータタイプ(サイズ)インデックスのテーブルです。

ステップ2:-変数名typename;

Morinformationの場合>>> テーブル(または)PL/SQLテーブル(または)連想配列によるPL/SQLインデックス

0
Dayakark