Oracleのコレクションに぀いお

この蚘事にはかなり論文スタむルがありたす。 より詳现な内容は、蚘事の最埌にある添付のビデオに蚘茉されおおり、Oracleコレクションに関する講矩が収録されおいたす。

コレクションは、ほずんどのプログラミング蚀語で䜕らかの圢で存圚し、どこでも䜿甚の点で同様の本質を持っおいたす。 ぀たり、同じタむプのオブゞェクトのセットを保存し、セット党䜓に察しおアクションを実行したり、サむクル内のセットのすべおの芁玠に察しお同じアクションを実行したりできたす。

コレクションは、Oracleでも同じように䜿甚されたす。

蚘事の内容




pl / sqlのコレクションの抂芁



コレクションの皮類

収集タむプアむテム数むンデックスの皮類密たたは疎初期化なし発衚堎所SQLでの䜿甚
連想配列
テヌブルによるむンデックス
蚭定されおいたせんひも
Pls_integer
密で疎空のPL / SQLブロック
パッケヌゞ
いや
VARRAY
可倉サむズの配列
によっお蚭定敎数高密床のみヌルPL / SQLブロック
パッケヌゞ
スキヌマレベル
スキヌマ固有のみ
入れ子になったテヌブル蚭定されおいたせん敎数密に䜜成するず、たばらになるこずがありたすヌルPL / SQLブロック
パッケヌゞ
スキヌマレベル
スキヌマ固有のみ

コレクションの密床ずは、コレクションの芁玠間にギャップや空きスペヌスがないこずを意味したす。 衚からわかるように、䞀郚のコレクションはスパヌスである可胜性がありたす。 芁玠間にギャップがある堎合がありたす。 これは、たずえば、コレクション内にむンデックス1ず4の芁玠があり、むンデックス2ず3には芁玠がないこずを意味したす。 この堎合、2番目ず3番目の芁玠のメモリスロットは存圚し、コレクションネストされたテヌブルの堎合に属したすが、オブゞェクトを含たず、これらの芁玠の内容を読み取ろうずするずno_data_found゚ラヌが発生したす。
詳现は、蚘事の最埌にあるビデオ講矩に蚘茉されおいたす。

連想配列


テヌブルたたはpl / sqlテヌブルによるむンデックスずも呌ばれたす。
タむプは次のように説明されたすassoc_array_type_def:。



に䜿甚


制限
連想配列を埋めた埌、セッション䞭にNLS_SORTおよびNLS_COMPパラメヌタヌを倉曎するず、最初、最埌、次、前のメ゜ッドの呌び出しから予期しない結果が埗られる堎合がありたす。 たた、連想配列をパラメヌタヌずしお別のデヌタベヌスに枡す際に、異なるNLS_SORTおよびNLS_COMP蚭定を持぀問題がある堎合がありたす。

VARRAY

これは、順次保存されるアむテムの配列です。


タむプは次のように蚘述されたすvaray_type_def




次の堎合に䜿甚


制限
最倧サむズ-2,147,483,647アむテム

入れ子になったテヌブル

タむプは次のように蚘述されたすnested_table_type_def




ネストされたテヌブルを䜿甚したセット操䜜

操䜜は、 ネストした衚コレクションでのみ可胜です。 操䜜に参加する䞡方のコレクションは同じタむプである必芁がありたす。
操䜜の結果は、 ネストした衚のコレクションでもありたす 。

運営説明
マルチセットナニオン2぀のコレクションの和集合を返したす
マルチセットナニオンの区別重耇のない2぀のコレクションの和集合を返したす重耇を削陀したす
マルチセットの亀差2぀のコレクションの共通郚分を返したす
マルチセット亀差の区別重耇のない2぀のコレクションの共通郚分を返したす重耇を削陀したす
セット異なるコレクションテむクのないコレクションを返したす
マルチセットを陀く2぀のコレクションの差を返したす
DISTINCTを陀くマルチセット2぀のコレクションの違いを個別に返したす重耇を削陀したす

小さな䟋
小さな䟋 MULTISET EXCEPT DISTINCT操䜜の結果に泚意しおください
 DECLARE TYPE nested_typ IS TABLE OF NUMBER; nt1 nested_typ := nested_typ(1,2,3); nt2 nested_typ := nested_typ(3,2,1); nt3 nested_typ := nested_typ(2,3,1,3); nt4 nested_typ := nested_typ(1,2,4); answer nested_typ; BEGIN answer := nt1 MULTISET UNION nt4; answer := nt1 MULTISET UNION nt3; answer := nt1 MULTISET UNION DISTINCT nt3; answer := nt2 MULTISET INTERSECT nt3; answer := nt2 MULTISET INTERSECT DISTINCT nt3; answer := SET(nt3); answer := nt3 MULTISET EXCEPT nt2; answer := nt3 MULTISET EXCEPT DISTINCT nt2; END; 


結果
 nt1 MULTISET UNION nt4: 1 2 3 1 2 4 nt1 MULTISET UNION nt3: 1 2 3 2 3 1 3 nt1 MULTISET UNION DISTINCT nt3: 1 2 3 nt2 MULTISET INTERSECT nt3: 3 2 1 nt2 MULTISET INTERSECT DISTINCT nt3: 3 2 1 SET(nt3): 2 3 1 nt3 MULTISET EXCEPT nt2: 3 nt3 MULTISET EXCEPT DISTINCT nt2: empty set 



コレクションを䜿甚した論理挔算

運営説明
IS NULLIS NOT NULLコレクションをNULLず比范したす
比范=2぀のネストされたテヌブルコレクションは、それらが同じタむプで、タむプがrecordのレコヌドを含たない堎合に比范できたす。 同じ芁玠セットを持っおいる堎合は同じですコレクション内の芁玠の栌玍順序に関係なく
でコレクションを括匧内のコレクションず比范したす
郚分集合コレクションが別のコレクションのサブセットであるかどうかを確認したす。
のメンバヌ特定のアむテムオブゞェクトがコレクションの䞀郚であるかどうかを確認したす。
セットですコレクションに重耇が含たれおいるかどうかを確認したす
空ですコレクションが空かどうかを確認したす


論理的な収集操䜜を䜿甚する小さな䟋
 DECLARE TYPE nested_typ IS TABLE OF NUMBER; nt1 nested_typ := nested_typ(1, 2, 3); nt2 nested_typ := nested_typ(3, 2, 1); nt3 nested_typ := nested_typ(2, 3, 1, 3); nt4 nested_typ := nested_typ(); BEGIN IF nt1 = nt2 THEN DBMS_OUTPUT.PUT_LINE('nt1 = nt2'); END IF; IF (nt1 IN (nt2, nt3, nt4)) THEN DBMS_OUTPUT.PUT_LINE('nt1 IN (nt2,nt3,nt4)'); END IF; IF (nt1 SUBMULTISET OF nt3) THEN DBMS_OUTPUT.PUT_LINE('nt1 SUBMULTISET OF nt3'); END IF; IF (3 MEMBER OF nt3) THEN DBMS_OUTPUT.PUT_LINE('3 MEMBER OF nt3'); END IF; IF (nt3 IS NOT A SET) THEN DBMS_OUTPUT.PUT_LINE('nt3 IS NOT A SET'); END IF; IF (nt4 IS EMPTY) THEN DBMS_OUTPUT.PUT_LINE('nt4 IS EMPTY'); END IF; END; 


結果
 nt1 = nt2 nt1 IN (nt2,nt3,nt4) nt1 SUBMULTISET OF nt3 3 MEMBER OF nt3 nt3 IS NOT A SET nt4 IS EMPTY 



収集方法

メ゜ッド呌び出しの構文
 collection_name.method 

方法皮類説明テヌブルごずのむンデックスVARRAY入れ子になったテヌブル
削陀手続きコレクションからアむテムを削陀したす。はいパラメヌタなしのバヌゞョンのみはい
トリム手続きコレクションの最埌からアむテムを削陀したすコレクションの内郚サむズで動䜜したすいやはいはい
延長手続きコレクションの最埌にアむテムを远加したす。いやはいはい
存圚する機胜アむテムがコレクション内にある堎合、TRUEを返したす。はいはいはい
最初機胜コレクションの最初のむンデックスを返したすはいはいはい
最埌機胜最埌のコレクションむンデックスを返したすはいはいはい
COUNT機胜コレクション内のアむテムの数を返したす。はいはいはい
限界機胜コレクションが保存できるアむテムの最倧数を返したす。いやはいいや
事前機胜コレクション内の前のアむテムのむンデックスを返したす。はいはいはい
次ぞ機胜コレクション内の次のアむテムのむンデックスを返したすはいはいはい


削陀する
  • 削陀するず、すべおのアむテムが削陀されたす。 これらのアむテムを保存するために割り圓おられたメモリをすぐにクリアしたす。
  • 削陀nは、むンデックスnの芁玠を削陀したす。 メモリが解攟されたせん。 芁玠を埩元する぀たり、新しい芁玠を蚭定するず、前の芁玠ず同じメモリを占有したす。
  • Deleten、mは、間隔n..mのむンデックスを持぀芁玠を削陀したす
  • コレクションに削陀するアむテムがない堎合、䜕も実行されたせん。
  • VARRAY型のコレクションの堎合、パラメヌタなしのメ゜ッドのバヌゞョンのみが䜿甚可胜です


䜿甚䟋
 DECLARE TYPE nt_type IS TABLE OF NUMBER; nt nt_type := nt_type(11, 22, 33, 44, 55, 66); BEGIN nt.DELETE(2); --    nt(2) := 2222; --  2-  nt.DELETE(2, 4); --    2-  4- nt(3) := 3333; --  3-  nt.DELETE; --    END; 

結果
 beginning: 11 22 33 44 55 66 after delete(2): 11 33 44 55 66 after nt(2) := 2222: 11 2222 33 44 55 66 after delete(2, 4): 11 55 66 after nt(3) := 3333: 11 3333 55 66 after delete: empty set 



トリム



䜿甚䟋
 DECLARE TYPE nt_type IS TABLE OF NUMBER; nt nt_type := nt_type(11, 22, 33, 44, 55, 66); BEGIN nt.TRIM; -- Trim last element nt.DELETE(4); -- Delete fourth element nt.TRIM(2); -- Trim last two elements END; 

結果
 beginning: 11 22 33 44 55 66 after TRIM: 11 22 33 44 55 after DELETE(4): 11 22 33 55 after TRIM(2): 11 22 33 



延長



䜿甚䟋
 DECLARE TYPE nt_type IS TABLE OF NUMBER; nt nt_type := nt_type(11, 22, 33); BEGIN nt.EXTEND(2, 1); -- Append two copies of first element nt.DELETE(5); -- Delete fifth element nt.EXTEND; -- Append one null element END; 

結果
 beginning: 11 22 33 after EXTEND(2,1): 11 22 33 11 11 after DELETE(5): 11 22 33 11 after EXTEND: 11 22 33 11 



存圚する


䜿甚䟋
 DECLARE TYPE NumList IS TABLE OF INTEGER; n NumList := NumList(1, 3, 5, 7); BEGIN n.DELETE(2); -- Delete second element FOR i IN 1 .. 6 LOOP IF n.EXISTS(i) THEN DBMS_OUTPUT.PUT_LINE('n('||i||') = ' || n(i)); ELSE DBMS_OUTPUT.PUT_LINE('n('||i||') does not exist'); END IF; END LOOP; END; 



最初ず最埌


䜿甚䟋
 DECLARE TYPE aa_type_str IS TABLE OF INTEGER INDEX BY VARCHAR2(10); aa_str aa_type_str; BEGIN aa_str('Z') := 26; aa_str('A') := 1; aa_str('K') := 11; aa_str('R') := 18; DBMS_OUTPUT.PUT_LINE('Before deletions:'); DBMS_OUTPUT.PUT_LINE('FIRST = ' || aa_str.FIRST); DBMS_OUTPUT.PUT_LINE('LAST = ' || aa_str.LAST); aa_str.DELETE('A'); aa_str.DELETE('Z'); DBMS_OUTPUT.PUT_LINE('After deletions:'); DBMS_OUTPUT.PUT_LINE('FIRST = ' || aa_str.FIRST); DBMS_OUTPUT.PUT_LINE('LAST = ' || aa_str.LAST); END; 

結果
 Before deletions: FIRST = A LAST = Z After deletions: FIRST = K LAST = R 



カりント

䜿甚䟋
 DECLARE TYPE NumList IS VARRAY(10) OF INTEGER; n NumList := NumList(1, 3, 5, 7); BEGIN DBMS_OUTPUT.PUT('n.COUNT = ' || n.COUNT || ', '); DBMS_OUTPUT.PUT_LINE('n.LAST = ' || n.LAST); n.EXTEND(3); DBMS_OUTPUT.PUT('n.COUNT = ' || n.COUNT || ', '); DBMS_OUTPUT.PUT_LINE('n.LAST = ' || n.LAST); n.TRIM(5); DBMS_OUTPUT.PUT('n.COUNT = ' || n.COUNT || ', '); DBMS_OUTPUT.PUT_LINE('n.LAST = ' || n.LAST); END; 

結果
 n.COUNT = 4, n.LAST = 4 n.COUNT = 7, n.LAST = 7 n.COUNT = 2, n.LAST = 2 



制限


䜿甚䟋
 DECLARE TYPE aa_type IS TABLE OF INTEGER INDEX BY PLS_INTEGER; aa aa_type; -- associative array TYPE va_type IS VARRAY(4) OF INTEGER; va va_type := va_type(2, 4); -- varray TYPE nt_type IS TABLE OF INTEGER; nt nt_type := nt_type(1, 3, 5); -- nested table BEGIN aa(1) := 3; aa(2) := 6; aa(3) := 9; aa(4) := 12; DBMS_OUTPUT.PUT_LINE('aa.COUNT = ' || aa.count); DBMS_OUTPUT.PUT_LINE('aa.LIMIT = ' || aa.limit); DBMS_OUTPUT.PUT_LINE('va.COUNT = ' || va.count); DBMS_OUTPUT.PUT_LINE('va.LIMIT = ' || va.limit); DBMS_OUTPUT.PUT_LINE('nt.COUNT = ' || nt.count); DBMS_OUTPUT.PUT_LINE('nt.LIMIT = ' || nt.limit); END; 

結果
 aa.COUNT = 4 aa.LIMIT = va.COUNT = 2 va.LIMIT = 4 nt.COUNT = 3 nt.LIMIT = 



前ず次


䜿甚䟋
 DECLARE TYPE nt_type IS TABLE OF NUMBER; nt nt_type := nt_type(18, NULL, 36, 45, 54, 63); BEGIN nt.DELETE(4); DBMS_OUTPUT.PUT_LINE('nt(4) was deleted.'); FOR i IN 1 .. 7 LOOP DBMS_OUTPUT.PUT('nt.PRIOR(' || i || ') = '); print(nt.PRIOR(i)); DBMS_OUTPUT.PUT('nt.NEXT(' || i || ') = '); print(nt.NEXT(i)); END LOOP; END; 

結果
 nt(4) was deleted. nt.PRIOR(1) = nt.NEXT(1) = 2 nt.PRIOR(2) = 1 nt.NEXT(2) = 3 nt.PRIOR(3) = 2 nt.NEXT(3) = 5 nt.PRIOR(4) = 3 nt.NEXT(4) = 5 nt.PRIOR(5) = 3 nt.NEXT(5) = 6 nt.PRIOR(6) = 5 nt.NEXT(6) = nt.PRIOR(7) = 6 nt.NEXT(7) = 



䞀括収集



䜿甚䟋
 DECLARE TYPE NumTab IS TABLE OF employees.employee_id%TYPE; TYPE NameTab IS TABLE OF employees.last_name%TYPE; CURSOR c1 IS SELECT employee_id,last_name FROM employees WHERE salary > 10000 ORDER BY last_name; enums NumTab; names NameTab; BEGIN SELECT employee_id, last_name BULK COLLECT INTO enums, names FROM employees ORDER BY employee_id; OPEN c1; LOOP FETCH c1 BULK COLLECT INTO enums, names LIMIT 10; EXIT WHEN names.COUNT = 0; do_something(); END LOOP; CLOSE c1; DELETE FROM emp_temp WHERE department_id = 30 RETURNING employee_id, last_name BULK COLLECT INTO enums, names; END; 



forallサむクル





䜿甚䟋
 DECLARE TYPE NumList IS TABLE OF NUMBER; depts NumList := NumList(10, 20, 30); TYPE enum_t IS TABLE OF employees.employee_id%TYPE; e_ids enum_t; TYPE dept_t IS TABLE OF employees.department_id%TYPE; d_ids dept_t; BEGIN FORALL j IN depts.FIRST .. depts.LAST DELETE FROM emp_temp WHERE department_id = depts(j) RETURNING employee_id, department_id BULK COLLECT INTO e_ids, d_ids; END; 



forallの䟋倖



収集の䟋倖



䟋倖をスロヌする状況の䟋
 DECLARE TYPE NumList IS TABLE OF NUMBER; nums NumList; BEGIN nums(1) := 1; -- raises COLLECTION_IS_NULL nums := NumList(1, 2); nums(NULL) := 3; -- raises VALUE_ERROR nums(0) := 3; -- raises SUBSCRIPT_BEYOND_COUNT nums(3) := 3; --raises SUBSCRIPT_OUTSIDE_LIMIT nums.Delete(1); IF nums(1) = 1 THEN ... -- raises NO_DATA_FOUND END; 



DBMS_SESSION.FREE_UNUSED_USER_MEMORY




その堎合、メモリを解攟する必芁がありたす。


䜿甚䟋
 CREATE PACKAGE foobar type number_idx_tbl is table of number indexed by binary_integer; store1_table number_idx_tbl; -- PL/SQL indexed table store2_table number_idx_tbl; -- PL/SQL indexed table store3_table number_idx_tbl; -- PL/SQL indexed table ... END; -- end of foobar DECLARE ... empty_table number_idx_tbl; -- uninitialized ("empty") version BEGIN FOR i in 1..1000000 loop store1_table(i) := i; -- load data END LOOP; ... store1_table := empty_table; -- "truncate" the indexed table ... - dbms_session.free_unused_user_memory; -- give memory back to system store1_table(1) := 100; -- index tables still declared; store2_table(2) := 200; -- but truncated. ... END; 



この蚘事の執筆に基づいた講矩のビデオ録画



Oracleのトピックに関する他の倚くのビデオは、このチャンネルで芋぀けるこずができたす。
www.youtube.com/c/MoscowDevelopmentTeam

その他のOracleの蚘事


Oracleのトリガヌに぀いお

Source: https://habr.com/ru/post/J254355/


All Articles