Oracle คอลเลกชัน PL/SQL: วาร์เรย์ ซ้อนกัน และจัดทำดัชนีตามตาราง
คอลเลกชันคืออะไร?
คอลเลกชันคือกลุ่มขององค์ประกอบที่มีลำดับของประเภทข้อมูลเฉพาะ ซึ่งอาจเป็นคอลเลกชันของประเภทข้อมูลที่เรียบง่ายหรือประเภทข้อมูลที่ซับซ้อน (เช่น ประเภทที่ผู้ใช้กำหนดหรือประเภทระเบียน)
ในคอลเลกชัน แต่ละองค์ประกอบจะถูกระบุด้วยคำที่เรียกว่า “ตัวห้อย” แต่ละรายการในคอลเลกชันถูกกำหนดด้วยตัวห้อยที่ไม่ซ้ำกัน ข้อมูลในคอลเลกชันนั้นสามารถจัดการหรือดึงข้อมูลได้โดยอ้างอิงถึงตัวห้อยที่ไม่ซ้ำกันนั้น
คอลเลกชันเป็นสิ่งที่มีประโยชน์มากที่สุดเมื่อต้องประมวลผลหรือจัดการข้อมูลขนาดใหญ่ประเภทเดียวกัน คอลเลกชันสามารถเติมและจัดการโดยรวมได้โดยใช้ตัวเลือก 'BULK' ใน Oracle.
คอลเลกชันจะถูกจัดประเภทตามโครงสร้าง ตัวห้อย และพื้นที่จัดเก็บดังที่แสดงด้านล่าง
- ดัชนีต่อตาราง (หรือที่เรียกว่า Associative Array)
- ตารางที่ซ้อนกัน
- วาร์เรย์
ณ จุดใด ๆ ข้อมูลในคอลเลกชันสามารถอ้างอิงได้สามคำ ชื่อคอลเลกชัน ตัวห้อย ชื่อฟิลด์/คอลัมน์ เป็น “ - - - คุณจะได้เรียนรู้เกี่ยวกับหมวดหมู่คอลเลกชันที่กล่าวมาข้างต้นเพิ่มเติมในส่วนด้านล่าง
วาร์เรย์
Varray เป็นวิธีการรวบรวมซึ่งขนาดของอาร์เรย์ถูกกำหนดไว้ตายตัว ขนาดของอาร์เรย์ไม่สามารถเกินค่าที่กำหนดได้ ดัชนีของ Varray จะเป็นค่าตัวเลข ต่อไปนี้คือคุณลักษณะของ Varray
- ขนาดขีดจำกัดบนได้รับการแก้ไขแล้ว
- เติมตามลำดับโดยเริ่มด้วยตัวห้อย '1'
- ประเภทคอลเลกชันนี้มีความหนาแน่นอยู่เสมอ กล่าวคือ เราไม่สามารถลบองค์ประกอบอาร์เรย์ใดๆ ได้ Varray สามารถลบออกทั้งหมดหรือตัดออกตั้งแต่ตอนท้ายก็ได้
- เนื่องจากมีลักษณะหนาแน่นอยู่เสมอ จึงมีความยืดหยุ่นน้อยมาก
- เหมาะสมกว่าที่จะใช้เมื่อทราบขนาดอาเรย์และทำกิจกรรมที่คล้ายกันในองค์ประกอบอาเรย์ทั้งหมด
- ตัวห้อยและลำดับจะคงที่เสมอ กล่าวคือ ตัวห้อยและจำนวนคอลเลกชันจะเท่ากันเสมอ
- จำเป็นต้องเริ่มต้นใช้งานก่อนจึงจะใช้ในโปรแกรมได้ การดำเนินการใดๆ (ยกเว้นการดำเนินการ EXISTS) กับคอลเลกชันที่ไม่มีการเริ่มต้นใช้งานจะแสดงข้อผิดพลาด
- สามารถสร้างเป็นวัตถุฐานข้อมูลซึ่งมองเห็นได้ทั่วทั้งฐานข้อมูลหรือภายในโปรแกรมย่อยซึ่งสามารถใช้ได้เฉพาะในโปรแกรมย่อยนั้นเท่านั้น
รูปด้านล่างจะอธิบายการจัดสรรหน่วยความจำของ Varray (หนาแน่น) แบบไดอะแกรม
| ห้อย | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| ความคุ้มค่า | xyz | ดฟฟ | สเด | Cxs | วบีซี | นู | Qwe |
ไวยากรณ์สำหรับ VARRAY:
TYPE <type_name> IS VARRAY (<SIZE>) OF <DATA_TYPE>;
- ในรูปแบบข้างต้น type_name จะถูกประกาศเป็น VARRAY ของประเภท 'DATA_TYPE' สำหรับขีดจำกัดขนาดที่กำหนด ประเภทข้อมูลสามารถเป็นประเภทง่ายหรือซับซ้อนก็ได้
ตารางที่ซ้อนกัน
ตารางที่ซ้อนกันคือคอลเลกชันที่ขนาดของอาร์เรย์ไม่คงที่ มีประเภทตัวห้อยเป็นตัวเลข ด้านล่างนี้เป็นคำอธิบายเพิ่มเติมเกี่ยวกับประเภทตารางที่ซ้อนกัน
- ตารางที่ซ้อนกันไม่มีขีดจำกัดขนาดด้านบน
- เนื่องจากขีดจำกัดขนาดด้านบนไม่ได้รับการแก้ไข คอลเลกชันและหน่วยความจำจึงต้องขยายในแต่ละครั้งก่อนที่เราจะใช้งาน เราสามารถขยายคอลเลกชันโดยใช้คำหลัก 'EXTEND'
- เติมตามลำดับโดยเริ่มด้วยตัวห้อย '1'
- ประเภทคอลเลกชันนี้สามารถเป็นได้ทั้งสองอย่าง หนาแน่นและเบาบางกล่าวคือ เราสามารถสร้างคอลเลกชันแบบหนาแน่นได้ และเรายังสามารถลบองค์ประกอบอาร์เรย์แต่ละรายการแบบสุ่ม ซึ่งทำให้คอลเลกชันเป็นแบบกระจัดกระจาย
- มันให้ความยืดหยุ่นมากขึ้นในการลบองค์ประกอบอาร์เรย์
- มันถูกเก็บไว้ในตารางฐานข้อมูลที่ระบบสร้างขึ้นและสามารถนำมาใช้ในแบบสอบถามแบบใช้เลือกข้อมูลเพื่อดึงค่า
- ตัวห้อยและลำดับไม่เสถียร กล่าวคือ ตัวห้อยและจำนวนองค์ประกอบอาร์เรย์อาจแตกต่างกันไป
- จำเป็นต้องเริ่มต้นใช้งานก่อนจึงจะใช้ในโปรแกรมได้ การดำเนินการใดๆ (ยกเว้นการดำเนินการ EXISTS) กับคอลเลกชันที่ไม่ได้เริ่มต้นใช้งานจะแสดงข้อผิดพลาด
- สามารถสร้างเป็นวัตถุฐานข้อมูลซึ่งมองเห็นได้ทั่วทั้งฐานข้อมูลหรือภายในโปรแกรมย่อยซึ่งสามารถใช้ได้เฉพาะในโปรแกรมย่อยนั้นเท่านั้น
รูปด้านล่างจะอธิบายการจัดสรรหน่วยความจำของตารางที่ซ้อนกัน (หนาแน่นและกระจัดกระจาย) ตามแผนภาพ พื้นที่องค์ประกอบสีดำหมายถึงองค์ประกอบว่างในคอลเลกชัน เช่น กระจัดกระจาย
| ห้อย | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| ค่า (หนาแน่น) | xyz | ดฟฟ | สเด | Cxs | วบีซี | นู | Qwe |
| ค่า(เบาบาง) | Qwe | asd | อัฟกานิสถาน | asd | wer |
ไวยากรณ์สำหรับตารางที่ซ้อนกัน:
TYPE <tvpe name> IS TABLE OF <DATA TYPE>;
- ในรูปแบบข้างต้น type_name ถูกประกาศให้เป็นคอลเลกชันตารางแบบซ้อนของประเภท 'DATA_TYPE' ประเภทข้อมูลสามารถเป็นประเภทข้อมูลแบบง่ายหรือแบบซับซ้อนก็ได้
ดัชนีต่อตาราง
Index-by-table คือคอลเลกชันที่ขนาดอาร์เรย์ไม่คงที่ ไม่เหมือนกับคอลเลกชันประเภทอื่น ๆ ในคอลเลกชัน Index-by-table ผู้ใช้สามารถกำหนดดัชนีได้ ต่อไปนี้คือแอตทริบิวต์ของ Index-by-table
- ตัวห้อยสามารถเป็นจำนวนเต็มหรือสตริง ในขณะที่สร้างคอลเลกชัน ควรระบุประเภทตัวห้อย
- คอลเลกชันเหล่านี้ไม่ได้จัดเก็บตามลำดับ
- พวกมันจะเบาบางในธรรมชาติอยู่เสมอ
- ขนาดอาร์เรย์ไม่คงที่
- ไม่สามารถจัดเก็บไว้ในคอลัมน์ฐานข้อมูลได้ สิ่งเหล่านี้จะต้องถูกสร้างขึ้นและใช้ในโปรแกรมใด ๆ ในเซสชั่นนั้น ๆ
- ให้ความยืดหยุ่นมากขึ้นในแง่ของการรักษาตัวห้อย
- ตัวห้อยสามารถเป็นลำดับตัวห้อยเชิงลบได้เช่นกัน
- เหมาะสมกว่าที่จะใช้สำหรับค่ารวมที่ค่อนข้างเล็กซึ่งสามารถเริ่มต้นและใช้งานคอลเลกชันภายในโปรแกรมย่อยเดียวกันได้
- ไม่จำเป็นต้องเริ่มต้นก่อนเริ่มใช้งาน
- ไม่สามารถสร้างเป็นวัตถุฐานข้อมูลได้ สามารถสร้างได้ภายในโปรแกรมย่อยเท่านั้น ซึ่งสามารถใช้ได้เฉพาะในโปรแกรมย่อยนั้นเท่านั้น
- ไม่สามารถใช้ BULK COLLECT ในคอลเลกชันประเภทนี้ได้ เนื่องจากควรให้ตัวห้อยอย่างชัดเจนสำหรับแต่ละบันทึกในคอลเลกชัน
รูปด้านล่างจะอธิบายการจัดสรรหน่วยความจำของตารางที่ซ้อนกัน (กระจัดกระจาย) แบบไดอะแกรม พื้นที่องค์ประกอบสีดำหมายถึงองค์ประกอบว่างในคอลเลกชัน เช่น กระจัดกระจาย
| ตัวห้อย (varchar) | FIRST | นาปรัง | ที่สาม | FOURTH | ที่ห้า | หก | เจ็ด |
| ค่า(เบาบาง) | Qwe | asd | อัฟกานิสถาน | asd | wer |
ไวยากรณ์สำหรับดัชนีต่อตาราง
TYPE <type_name> IS TABLE OF <DATA_TYPE> INDEX BY VARCHAR2 (10);
- ในรูปแบบข้างต้น type_name จะถูกประกาศให้เป็นคอลเลกชันแบบดัชนีต่อตารางของประเภท 'DATA_TYPE' ประเภทข้อมูลสามารถเป็นประเภทง่ายหรือซับซ้อนก็ได้ ตัวแปร subsciprt/index ถูกกำหนดให้เป็นประเภท VARCHAR2 โดยมีขนาดสูงสุดที่ 10
คอนสตรัคเตอร์และแนวคิดการเริ่มต้นในคอลเลกชัน
Constructor คือฟังก์ชันในตัวที่จัดทำโดย Oracle ซึ่งมีชื่อเดียวกับชื่อของอ็อบเจ็กต์หรือคอลเลกชัน Constructor จะถูกดำเนินการก่อนทุกครั้งที่มีการอ้างอิงอ็อบเจ็กต์หรือคอลเลกชันเป็นครั้งแรกในเซสชัน ด้านล่างนี้คือรายละเอียดสำคัญของ Constructor ในบริบทของคอลเลกชัน:
- สำหรับคอลเลกชัน ควรเรียกตัวสร้างเหล่านี้อย่างชัดเจนเพื่อเริ่มต้น
- ทั้งตาราง Varray และ Nested จำเป็นต้องเริ่มต้นผ่าน Constructor เหล่านี้ก่อนที่จะอ้างอิงเข้าสู่โปรแกรม
- ตัวสร้างขยายการจัดสรรหน่วยความจำสำหรับคอลเลกชันโดยปริยาย (ยกเว้น Varray) ดังนั้นตัวสร้างจึงสามารถกำหนดตัวแปรให้กับคอลเลกชันได้
- การกำหนดค่าให้กับคอลเลกชันผ่านตัวสร้างจะไม่ทำให้คอลเลกชันกระจัดกระจาย
วิธีการเก็บรวบรวม
Oracle มีฟังก์ชันต่างๆ มากมายสำหรับจัดการและทำงานกับคอลเลกชัน ฟังก์ชันเหล่านี้มีประโยชน์มากในการกำหนดและปรับเปลี่ยนแอตทริบิวต์ต่างๆ ของคอลเลกชัน ตารางต่อไปนี้จะแสดงฟังก์ชันต่างๆ และคำอธิบายของฟังก์ชันเหล่านั้น
| วิธี | Descriptไอออน | ซิงค์ |
|---|---|---|
| มีอยู่ (n) | วิธีนี้จะส่งคืนผลลัพธ์แบบบูลีน มันจะคืนค่า 'TRUE' ถ้า nth มีองค์ประกอบอยู่ในคอลเล็กชันนั้น มิเช่นนั้นจะส่งคืนค่า FALSE เฉพาะฟังก์ชัน EXISTS เท่านั้นที่สามารถนำมาใช้ในคอลเลกชันที่ไม่ได้เตรียมใช้งาน | .มีอยู่(element_position) |
| COUNT | แสดงจำนวนองค์ประกอบทั้งหมดที่มีอยู่ในคอลเลกชัน | .นับ |
| LIMIT | มันจะส่งกลับขนาดสูงสุดของคอลเลกชัน สำหรับ Varray มันจะส่งคืนขนาดคงที่ที่กำหนดไว้ สำหรับตารางที่ซ้อนกันและดัชนีต่อตาราง จะให้ค่า NULL | .จำกัด |
| FIRST | ส่งกลับค่าของตัวแปรดัชนีตัวแรก (ตัวห้อย) ของคอลเลกชัน | .อันดับแรก |
| LAST | ส่งกลับค่าของตัวแปรดัชนีล่าสุด (ตัวห้อย) ของคอลเลกชัน | .ล่าสุด |
| ก่อน (n) | ส่งกลับนำหน้าตัวแปรดัชนีในคอลเลกชันของ nth องค์ประกอบ. หากไม่มีค่าดัชนีนำหน้า NULL จะถูกส่งกลับ | .ก่อน(n) |
| ถัดไป (n) | ส่งคืนตัวแปรดัชนีสำเร็จในชุดของ nth องค์ประกอบ. หากไม่มีค่าดัชนีสำเร็จ NULL จะถูกส่งกลับ | .ถัดไป(n) |
| ขยาย | ขยายหนึ่งองค์ประกอบในคอลเลกชันที่ส่วนท้าย | .ขยาย |
| ขยาย (n) | ขยายองค์ประกอบ n ที่ส่วนท้ายของคอลเลกชัน | .ขยาย(n) |
| ขยาย (n,i) | ขยายสำเนาของ ith องค์ประกอบที่ส่วนท้ายของคอลเลกชัน | .ขยาย(n,i) |
| TRIM | ลบองค์ประกอบหนึ่งรายการออกจากจุดสิ้นสุดของคอลเลกชัน | .ทริม |
| ตัดแต่ง (n) | ลบองค์ประกอบ n ออกจากจุดสิ้นสุดของการรวบรวม | .ทริม (n) |
| ลบ | ลบองค์ประกอบทั้งหมดออกจากคอลเลกชัน ทำให้คอลเลกชันว่างเปล่า | .ลบ |
| ลบ (n) | ลบองค์ประกอบที่ n ออกจากคอลเลกชัน ถ้าไม่มีth องค์ประกอบเป็น NULL จากนั้นจะไม่ทำอะไรเลย | .ลบ(n) |
| ลบ (นาที,n) | ลบองค์ประกอบในช่วง mth ถึง nth ในคอลเลกชั่น | .DELETE(ม,n) |
ตัวอย่างที่ 1: ประเภทเรคคอร์ดในระดับโปรแกรมย่อย
ในตัวอย่างนี้ เราจะดูวิธีการเติมข้อมูลคอลเลกชันโดยใช้ 'รวบรวมจำนวนมาก' และวิธีการอ้างอิงข้อมูลการรวบรวม
DECLARE
TYPE emp_det IS RECORD
(
EMP_NO NUMBER,
EMP_NAME VARCHAR2(150),
MANAGER NUMBER,
SALARY NUMBER
);
TYPE emp_det_tbl IS TABLE OF emp_det; guru99_emp_rec emp_det_tbl:= emp_det_tbl();
BEGIN
INSERT INTO emp (emp_no,emp_name, salary, manager) VALUES (1000,’AAA’,25000,1000);
INSERT INTO emp (emp_no,emp_name, salary, manager) VALUES (1001,'XXX’,10000,1000);
INSERT INTO emp (emp_no, emp_name, salary, manager) VALUES (1002,'YYY',15000,1000);
INSERT INTO emp (emp_no,emp_name,salary, manager) VALUES (1003,’ZZZ’,'7500,1000);
COMMIT:
SELECT emp no,emp_name,manager,salary BULK COLLECT INTO guru99_emp_rec
FROM emp;
dbms_output.put_line (‘Employee Detail');
FOR i IN guru99_emp_rec.FIRST..guru99_emp_rec.LAST
LOOP
dbms_output.put_line (‘Employee Number: '||guru99_emp_rec(i).emp_no);
dbms_output.put_line (‘Employee Name: '||guru99_emp_rec(i).emp_name);
dbms_output.put_line (‘Employee Salary:'|| guru99_emp_rec(i).salary);
dbms_output.put_line(‘Employee Manager Number:'||guru99_emp_rec(i).manager);
dbms_output.put_line('--------------------------------');
END LOOP;
END;
/
คำอธิบายรหัส:
- รหัสบรรทัด 2-8: ประเภทบันทึก 'emp_det' ถูกประกาศด้วยคอลัมน์ emp_no, emp_name, เงินเดือน และผู้จัดการประเภทข้อมูล NUMBER, VARCHAR2, NUMBER, NUMBER
- รหัสบรรทัด 9: การสร้างคอลเลกชัน 'emp_det_tbl' ขององค์ประกอบประเภทบันทึก 'emp_det'
- รหัสบรรทัด 10: ประกาศตัวแปร 'guru99_emp_rec' เป็นประเภท 'emp_det_tbl' และเริ่มต้นด้วยตัวสร้าง null
- รหัสบรรทัด 12-15: การแทรกข้อมูลตัวอย่างลงในตาราง 'emp'
- รหัสบรรทัด 16: ยืนยันธุรกรรมการแทรก
- รหัสบรรทัด 17: ดึงข้อมูลบันทึกจากตาราง 'emp' และเติมตัวแปรคอลเลกชันเป็นกลุ่มโดยใช้คำสั่ง "BULK COLLECT" ตอนนี้ตัวแปร 'guru99_emp_rec' มีบันทึกทั้งหมดที่มีอยู่ในตาราง 'emp'
- รหัสบรรทัด 19-26: การตั้งค่าการวนซ้ำ 'FOR' เพื่อใช้พิมพ์บันทึกทั้งหมดในคอลเลกชันทีละรายการ วิธีการรวบรวม FIRST และ LAST ใช้เป็นขีดจำกัดล่างและสูงกว่าของ ห่วง.
เอาท์พุต:ดังที่คุณเห็นในภาพหน้าจอด้านบน เมื่อดำเนินการโค้ดด้านบน คุณจะได้รับผลลัพธ์ดังต่อไปนี้
Employee Detail Employee Number: 1000 Employee Name: AAA Employee Salary: 25000 Employee Manager Number: 1000 ---------------------------------------------- Employee Number: 1001 Employee Name: XXX Employee Salary: 10000 Employee Manager Number: 1000 ---------------------------------------------- Employee Number: 1002 Employee Name: YYY Employee Salary: 15000 Employee Manager Number: 1000 ---------------------------------------------- Employee Number: 1003 Employee Name: ZZZ Employee Salary: 7500 Employee Manager Number: 1000 ----------------------------------------------

