« Sun Business Next 2007 | トップページ | Mac De Oracle : PL/SQL de Collection #3 »

2007年5月25日 (金)

Mac De Oracle : PL/SQL de Collection #2

PL/SQL de Collectionのつづきです。

VarrayとNested Tableを利用するには、まず最初に初期化する必要がある。(Associated Arrayでは、その必要はない。)
オブジェクト指向的だとインスタンスの作成と言ったほうが分かりやすいですかね。

以下、VarrayType型とNestedTableType型では、インスタンスを作成しないと、Javaで言うところのNull Pointer Exceptionが発生する。という例。
PL/SQLなのでNull Pointer Exceptionではなく、ORA-6531が発生するのですがね。
(私個人としては、ORA-6531より、ORA-2309: atomic NULL violation の方がストレートで分かりやすいんでない? なんて思う事しばしば。初めてNested Tableを使おうとして、そのメッセージの意味が分からずハマったことも。。。)

SCOTT> l
1 DECLARE
2 -- VARRAY
3 TYPE VarrayType IS VARRAY(100) OF empType;
4 -- NESTED TABLE
5 TYPE NestedTableType IS TABLE OF empType;
6 -- ASSOCIATIVE ARRAY (formaly called PL/SQL TABLE)
7 TYPE StrAssociativeArrayType IS TABLE OF empType INDEX BY VARCHAR2(50);
8 TYPE NumAssociativeArrayType IS TABLE OF empType INDEX BY BINARY_INTEGER;
9
10 myVarray VarrayType;
11 myNestedTable NestedTableType;
12 myStrAssociativeArray StrAssociativeArrayType;
13 myNumAssociativeArray NumAssociativeArrayType;
14 BEGIN
15 DBMS_OUTPUT.PUT_LINE('Associative Array:' || myStrAssociativeArray.COUNT());
16
17 BEGIN
18 DBMS_OUTPUT.PUT_LINE('Varray:' || myVarray.COUNT());
19 EXCEPTION
20 WHEN OTHERS THEN
21 DBMS_OUTPUT.PUT_LINE('Varray: ' || SQLERRM());
22 END;
23
24 BEGIN
25 DBMS_OUTPUT.PUT_LINE('Nested Table:' || myNestedTable.COUNT());
26 EXCEPTION
27 WHEN OTHERS THEN
28 DBMS_OUTPUT.PUT_LINE('Nested Table:' || SQLERRM());
29 END;
30* END;
SCOTT> /
Associative Array:0
Varray: ORA-06531: 参照しているコレクションは初期化されていません。
Nested Table:ORA-06531: 参照しているコレクションは初期化されていません。

PL/SQLプロシージャが正常に完了しました。

SCOTT>


ちなみに、Associative Arrayは、atomic nullには出来ない。やってみれば分かると思いますが、コンパイルエラーになります。
なのでこの点については、コンパイラから注意されるので特に問題はないでしょうね。

SCOTT> l
1 DECLARE
2 -- VARRAY
3 TYPE VarrayType IS VARRAY(100) OF empType;
4 -- NESTED TABLE
5 TYPE NestedTableType IS TABLE OF empType;
6 -- ASSOCIATIVE ARRAY (formaly called PL/SQL TABLE)
7 TYPE StrAssociativeArrayType IS TABLE OF empType INDEX BY VARCHAR2(50);
8 TYPE NumAssociativeArrayType IS TABLE OF empType INDEX BY BINARY_INTEGER;
9
10 myVarray VarrayType;
11 myNestedTable NestedTableType;
12 myStrAssociativeArray StrAssociativeArrayType;
13 myNumAssociativeArray NumAssociativeArrayType;
14 BEGIN
15 myStrAssociativeArray := NULL;
16 DBMS_OUTPUT.PUT_LINE('Associative Array:' || myStrAssociativeArray.COUNT());
17
18 myVarray := NULL;
19 BEGIN
20 DBMS_OUTPUT.PUT_LINE('Varray:' || myVarray.COUNT());
21 EXCEPTION
22 WHEN OTHERS THEN
23 DBMS_OUTPUT.PUT_LINE('Varray: ' || SQLERRM());
24 END;
25
26 myNestedTable := NULL;
27 BEGIN
28 DBMS_OUTPUT.PUT_LINE('Nested Table:' || myNestedTable.COUNT());
29 EXCEPTION
30 WHEN OTHERS THEN
31 DBMS_OUTPUT.PUT_LINE('Nested Table:' || SQLERRM());
32 END;
33* END;
SCOTT> /
myStrAssociativeArray := NULL;
*
行14でエラーが発生しました。:
ORA-06550: 行15、列28:
PLS-00382: 式の型が正しくありません。
ORA-06550: 行15、列3:
PL/SQL: Statement ignored


SCOTT>


VarrayやNested Tableを利用する際には、事前にコンストラクタを実行して初期化しておく必要がありますが、実行時エラーの危険を避けるため、定義時に初期化しておく方が無難でしょう。
以下の例では、各変数の宣言時にコンストラクタであるVarrayType()や、NestedTableType()を実行し初期化しています。

SCOTT> l
1 DECLARE
2 -- VARRAY
3 TYPE VarrayType IS VARRAY(100) OF empType;
4 -- NESTED TABLE
5 TYPE NestedTableType IS TABLE OF empType;
6 -- ASSOCIATIVE ARRAY (formaly called PL/SQL TABLE)
7 TYPE StrAssociativeArrayType IS TABLE OF empType INDEX BY VARCHAR2(50);
8 TYPE NumAssociativeArrayType IS TABLE OF empType INDEX BY BINARY_INTEGER;
9
10 myVarray VarrayType := VarrayType();
11 myNestedTable NestedTableType := NestedTableType();
12 myStrAssociativeArray StrAssociativeArrayType;
13 myNumAssociativeArray NumAssociativeArrayType;
14 BEGIN
15 DBMS_OUTPUT.PUT_LINE('Associative Array:' || myStrAssociativeArray.COUNT());
16 DBMS_OUTPUT.PUT_LINE('Varray:' || myVarray.COUNT());
17 DBMS_OUTPUT.PUT_LINE('Nested Table:' || myNestedTable.COUNT());
18* END;
SCOTT> /
Associative Array:0
Varray:0
Nested Table:0

PL/SQLプロシージャが正常に完了しました。

SCOTT>

こんどは問題なく要素数を表示できましたね。 この時点で、Associative Array、Varray、Nested Tableの各コレクションは空の状態。

尚、上記の例では、いきなりコレクションのメソッド (COUNT)を使っているが、コレクションで利用できるメソッドは以下のマニュアルで確認できる。
http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/appdev.102/B19257-01/langelems.html#6420

ということで、今日はここまで。

Oracleのオブジェクトに関しては、
http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/appdev.102/B19256-01/adobjint.htm#sthref39を中心に読めばそれなりに理解できるかと。

|

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/106341/15197379

この記事へのトラックバック一覧です: Mac De Oracle : PL/SQL de Collection #2:

コメント

コメントを書く