ネスト表とは、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 テーブルにデータがない場合は、NULL を返します。 |
| 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次元配列のようなものです。ネスト表と配列の主な違いは以下の通りです:
配列は要素数を宣言できますが、ネスト表はできません。ネスト表のサイズは動的に拡張可能です。
配列は常に密です。ネスト表は初期段階では密ですが、要素を削除することができるため疎になることもあります。
ネスト表の適用シナリオ
ネスト表は以下のシナリオに適しています:
要素数が未定義の場合。
インデックス値が連続していない場合。
特定の要素を削除または更新する必要があるが、すべての要素を一度に削除または更新することはできない場合。