در این قسمت انواع COLLECTION در PL/SQL را توضیح می دهیم. COLLECTION یک مجموعه ترتیبی از اجزای مختلف است که نوع داده یکسان دارند. سه مدل COLLECTION قابل تعریف و استفاده هستند که یکی از آنها Varray یا آرایه است که قبلا آن را توضیح دادیم.
در جدول زیر انواع COLLECTION و ویژگی های آنها را می بینید.
نکته 1 : منظور از نوع زیرنویس یا SUBSCRIPT همان کلیدی است که با استفاده از آن می توان به اجزای COLLECTION دسترسی داشت.
نکته 2 : نمی توان در COLLECTION های از نوع DENSE یک عنصر میانی را حذف نمود و فقط انتهای آن قابل تغییر می باشد بنابراین انعطاف پذیر نیستند.
چرا از COLLECTION استفاده می شود؟
1.سبب ایجاد سهولت در کد نویسی می شود.
2.زمانی که نیاز به پردازش اجزا با نوع داده یکسان است با استفاده از زیرنویس می توان به راحتی به تمام اجزا دسترسی یافت.
3.می توان از متودهای مختلف(FIRST,COUNT,…) کمک گرفت.
4.باعث PERFORMANCE بهتر در پردازش داده های موقتی برنامه ها می شود و نیاز به فراخوانی از دیتابیس را کمتر می کند.
COLLECTIONهای NESTED TABLE و INDEX BY TABLE ساختار یکسان دارند و سطرها یا اجزای آنها با استفاده از زیرنویس قابل دسترس هستند. در ادامه این نوع از جداول را توضیح می دهیم.
INDEX BY TABLE
در این دسته از COLLECTIONها زیرنویس ها UNIQUE هستند و می توانند از نوع INTEGER یا رشته باشند. در ادامه سینتکس ساخت INDEX BY TABLE را می بینید که در آن نوع داده اجزا و زیرنویس آنها مشخص می شود:
TYPE type_name IS TABLE OF element_type [NOT NULL] INDEX BY subscript_type;
table_name type_name;
مثال: یک جدول به صورت INDEX BY TABLE بسازید که مقدارهای عددی به همراه یک رشته 20 کاراکتری برای هر کدام از آنها را ذخیره کند.
نکته: متودهای FIRST و NEXT به اجزای اولیه و بعدی COLLECTION اشاره می کنند.
DECLARE
TYPE salary IS TABLE OF NUMBER INDEX BY VARCHAR2(20);
salary_list salary;
name VARCHAR2(20);
BEGIN
— adding elements to the table
salary_list(‘Rajnish’) := 62000;
salary_list(‘Minakshi’) := 75000;
salary_list(‘Martin’) := 100000;
salary_list(‘James’) := 78000;
— printing the table
name := salary_list.FIRST;
WHILE name IS NOT null LOOP
dbms_output.put_line
(‘Salary of ‘ || name || ‘ is ‘ || TO_CHAR(salary_list(name)));
name := salary_list.NEXT(name);
END LOOP;
END;
/
خروجی:
Salary of James is 78000
Salary of Martin is 100000
Salary of Minakshi is 75000
Salary of Rajnish is 62000
PL/SQL procedure successfully completed.
نکته: نوع داده اجزای INDEX BY TABLE می تواند با کلمه کلیدی ROWTYPE% معادل نوع داده یک جدول دیگر در دیتابیس در نظر گرفته شود یا با کلمه کلیدی TYPE% معادل نوع داده یک ستون از جدول دیگر باشد.
مثال: از نوع داده جدول customers استفاده نمایید و بجای متود FIRST و NEXT از CURSOR استفاده کنید.
Select * from customers;
+—-+———-+—–+———–+———-+
| ID | NAME | AGE | ADDRESS | SALARY |
+—-+———-+—–+———–+———-+
| 1 | Ramesh | 32 | Ahmedabad | 2000.00 |
| 2 | Khilan | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 5 | Hardik | 27 | Bhopal | 8500.00 |
| 6 | Komal | 22 | MP | 4500.00 |
+—-+———-+—–+———–+———-+
DECLARE
CURSOR c_customers is
select name from customers;
TYPE c_list IS TABLE of customerS.name%type INDEX BY binary_integer;
name_list c_list;
counter integer :=0;
BEGIN
FOR n IN c_customers LOOP
counter := counter +1;
name_list(counter) := n.name;
dbms_output.put_line(‘Customer(‘||counter|| ‘):’||name_list(counter));
END LOOP;
END;
/
خروجی:
Customer(1): Ramesh
Customer(2): Khilan
Customer(3): kaushik
Customer(4): Chaitali
Customer(5): Hardik
Customer(6): Komal
PL/SQL procedure successfully completed
NESTED TABLE
NESTED TABLE همانند یک آرایه است با این تفاوت که:
1.آرایه تعداد اجزای از قبل مشخص شده دارد ولی سایز یک NESTED TABLE می تواند به صورت پویا افزایش یابد.
2.آرایه به صورت DENSE است و ترتیب زیرنویس ها حفظ می شود ولی در NESTED TABLE می توان هرکدام از اجزای میانی را حذف نمود.
نکته: NESTED TABLEها برخلاف INDEX BY TABLEها می توانند در یک ستون از جدول های دیتابیس ذخیره شوند.
در ادامه سینتکس ساخت NESTED TABLE را می بینید.
TYPE type_name IS TABLE OF element_type [NOT NULL];
table_name type_name;
مثال:
DECLARE
TYPE names_table IS TABLE OF VARCHAR2(10);
TYPE grades IS TABLE OF INTEGER;
names names_table;
marks grades;
total integer;
BEGIN
names := names_table(‘Kavita’, ‘Pritam’, ‘Ayan’, ‘Rishav’, ‘Aziz’);
marks:= grades(98, 97, 78, 87, 92);
total := names.count;
dbms_output.put_line(‘Total ‘|| total || ‘ Students’);
FOR i IN 1 .. total LOOP
dbms_output.put_line(‘Student:’||names(i)||’, Marks:’ || marks(i));
end loop;
END;
/
خروجی:
Total 5 Students
Student:Kavita, Marks:98
Student:Pritam, Marks:97
Student:Ayan, Marks:78
Student:Rishav, Marks:87
Student:Aziz, Marks:92
PL/SQL procedure successfully completed.
نکته: نوع داده اجزای NESTED TABLE می تواند با کلمه کلیدی ROWTYPE% معادل نوع داده یک جدول دیگر در دیتابیس در نظر گرفته شود یا با کلمه کلیدی TYPE% معادل نوع داده یک ستون از جدول دیگر باشد.
مثال:
DECLARE
CURSOR c_customers is
SELECT name FROM customers;
TYPE c_list IS TABLE of customerS.name%type;
name_list c_list := c_list();
counter integer :=0;
BEGIN
FOR n IN c_customers LOOP
counter := counter +1;
name_list.extend;
name_list(counter) := n.name;
dbms_output.put_line(‘Customer(‘||counter||’):’||name_list(counter));
END LOOP;
END;
/
خروجی:
Customer(1): Ramesh
Customer(2): Khilan
Customer(3): kaushik
Customer(4): Chaitali
Customer(5): Hardik
Customer(6): Komal
PL/SQL procedure successfully completed.
متودهای COLLECTION
همانطور که در مثال های قبل ملاحظه کردید برای راحتی کار با COLLECTIONها در PL/SQL تعدادی متود در نظر گرفته شده است که می توان از آنها استفاده نمود. در جدول زیر فهرست متودها و دلیل استفاده از آنها را می بینید.
EXCEPTION ها
در جدول زیر خطاهایی که در COLLECTIONها رخ می دهند را ملاحظه می کنید.
ممنون از زحمات شما