ネストテーブルとは、PLプログラム内で配列を参照および模倣できる非永続的なテーブルです。
適用対象
この内容はOceanBaseデータベースEnterprise Editionにのみ適用されます。OceanBaseデータベースCommunity EditionはMySQLモードのみを提供します。
ユーザーはテーブル型を定義し、その型の変数を宣言することができます。その後、ユーザーはPLテーブルにレコードを追加し、配列要素を参照するのとほぼ同じ方法でレコードを参照できます。
構文は以下のとおりです:
TYPE type_name IS TABLE OF
{column_type | variable%TYPE | table.column%TYPE } [NOT NULL] | table%ROWTYPE
PLネストテーブル型がサポートする値の取得方法は、次の表に示されています。
| メソッド | 説明 |
|---|---|
| EXISTS(n) | n 番目の行が存在する場合、True を返します。 |
| COUNT | このPLテーブルの行数を返します。 |
| FIRST | LAST | 最初の行と最後の行(最小値と最大値)の行番号を返します。PLテーブルにデータがない場合は、空を返します。 |
| PRIOR(n) | PLテーブルの n 番目の行の前の行の行番号を返します。 |
| NEXT(n) | PLテーブルの n 番目の行の次の行の行番号を返します。 |
| DELETE |
|
ネストテーブルの例として、PLテーブルのレコードが削除されても、他のレコードの行番号は移動しません。
obclient> CREATE TABLE departments(department_id number(4),department_name varchar2(15));
Query OK, 0 rows affected
obclient> INSERT INTO departments VALUES(10,'Administration');
Query OK, 1 row affected
obclient> INSERT INTO departments VALUES(20,'Marketing');
Query OK, 1 row affected
obclient> INSERT INTO departments VALUES(30,'Purchasing');
Query OK, 1 row affected
obclient> INSERT INTO departments VALUES(40,'Human Resources');
Query OK, 1 row affected
obclient> INSERT INTO departments VALUES(50,'Shipping');
Query OK, 1 row affected
obclient> INSERT INTO departments VALUES(60,'IT');
Query OK, 1 row affected
obclient> DECLARE
TYPE t_dept_table IS TABLE OF departments%ROWTYPE INDEX BY BINARY_INTEGER;
tab_department T_DEPT_TABLE;
v_count number(2) :=6;
BEGIN
-- テーブルに値を代入
FOR int IN 1 .. v_count LOOP
SELECT * INTO tab_department(int) FROM departments WHERE department_id=int*10;
END LOOP;
-- COUNTを使用して合計行数を出力
DBMS_OUTPUT.PUT_LINE(tab_department.COUNT||' ROW(S): ');
-- FIRSTとLASTを使用してすべての行を出力
FOR int IN TAB_department.FIRST .. TAB_department.LAST LOOP
DBMS_OUTPUT.PUT_LINE('Department number: '||tab_department(int).department_id);
DBMS_OUTPUT.PUT_LINE('Department name: '|| tab_department(int).department_name);
END LOOP;
-- EXISTSを使用してレコードをチェック
IF tab_department.EXISTS(5) THEN
DBMS_OUTPUT.PUT_LINE('ROW 5 EXISTS');
ELSE
DBMS_OUTPUT.PUT_LINE('ROW 5 NOT EXISTS');
END IF;
-- DELETEを使用して範囲を削除
DBMS_OUTPUT.PUT_LINE('Delete row 2-3');
tab_department.DELETE(2,3);
-- NEXTを使用して前から後ろへレコードを出力
DBMS_OUTPUT.PUT_LINE('Looping from first');
v_count := 1;
WHILE v_count IS NOT NULL
LOOP
DBMS_OUTPUT.PUT_LINE(tab_department(v_count).department_id);
v_count := tab_department.next(v_count);
END LOOP;
-- PRIORを使用して後ろから前へ出力します。このときCOUNTは4です
DBMS_OUTPUT.PUT_LINE('Looping from last');
v_count := tab_department.COUNT;
WHILE v_count IS NOT NULL
LOOP
DBMS_OUTPUT.PUT_LINE(tab_department(v_count).department_id);
v_count := tab_department.prior(v_count);
END LOOP;
END;
/
Query OK, 0 rows affected
6 ROW(S):
Department number: 10
Department name: Administration
Department number: 20
Department name: Marketing
Department number: 30
Department name: Purchasing
Department number: 40
Department name: Human Resources
Department number: 50
Department name: Shipping
Department number: 60
Department name: IT
ROW 5 EXISTS
Delete row 2-3
Looping from first
10
40
50
60
Looping from last
40
10
ネストテーブルと配列の主な違い
概念的には、ネストテーブルは任意の数の要素を持つ1次元配列のようなものです。ネストテーブルと配列の主な違いは以下の通りです:
配列は要素数を宣言できますが、ネストテーブルはできません。ネストテーブルのサイズは動的に増加させることができます。
配列は常に密です。ネストテーブルは最初は密ですが、要素を削除することで疎になる可能性があります。
ネストテーブルの適用シナリオ
ネストテーブルは以下のシナリオに適しています:
要素数が設定されていない場合。
インデックス値が連続していない場合。
特定の要素を削除または更新する必要があるが、すべての要素を同時に削除または更新することはできない場合。