PL/SQL COLLECTION EXAMPLES
Sunday, July 9, 2017
Wednesday, September 2, 2015
PL/SQL COLLECTION EXAMPLES.
The following examples are taken from the book named THE PL/SQL REFERENCE 11G. The examples fall in chapter 5 which cover collections and records.
Example 5-1 : Declaring and Using an Associative Array.
----------------------------------------------------------------------
declare
type population is table of number index by varchar2(64);
city_population population;
i varchar2(64);
begin
city_population('SallVille') := 2000;
city_population('MidLand') := 750000;
city_population('Megaloplis') := 1000000;
i := city_population.first;
while i is not null loop
dbms_output.put_line('Population of '|| i || ' is ' || to_char(city_population(i)));
i := city_population.next(i);
end loop;
end;
/
Example 5-2 : Declaring an Associative Array.
--------------------------------------------------------
declare
type emptabtype is table of employees%rowtype index by pls_integer;
emp_tab emptabtype;
begin
select * into emp_tab(100) from employees where employee_id = 100;
end;
/
Example 5-3 : Declaring Nested Tables, Varrays and Associative Arrays.
----------------------------------------------------------------------------------------
declare
type nested_type is table of varchar2(30);
type nested_type2 is table of number;
type varray_type is varray(5) of integer;
type assoc_array_num_type is table of number index by pls_integer;
type assoc_array_str_type is table of varchar2(32) index by pls_integer;
type assoc_array_str_type2 is table of varchar2(32) index by varchar2(64);
v1 nested_type;
v2 varray_type;
v3 assoc_array_num_type;
v4 assoc_array_str_type;
v5 assoc_array_str_type2;
v6 nested_type2;
begin
v1 := nested_type('Shipping', 'Sales', 'Finance', 'Payroll');
v2 := varray_type(1, 2, 3, 4, 5);
v3(99) := 10;
v3(7) := 100;
v4(42) := 'Smith';
v4(54) := 'Johes';
v5('Canada') := 'North America';
v5('Greece') := 'Europe';
v6 := nested_type2(10, 20, 30, 40, 50);
dbms_output.put_line(v6(2));
end;
/
Example 5-4 : Declaring Collection with %Type;
------------------------------------------------------------
declare
type few_depts is varray(10) of varchar2(30);
type many_depts is varray(10) of varchar2(64);
some_depts few_depts;
local_depts some_depts%type;
globale_depts some_depts%type;
begin
local_depts := few_depts('ad', 'man', 'hr');
dbms_output.put_line(local_depts(1));
end;
/
Example 5-5 : Declaring a Procedure Parameter as a Nested Table.
---------------------------------------------------------------
Create or replace package personnel as
type staff_list is table of employees.employee_id%type;
procedure award_bonuses(empleos_buenos staff_list);
end personnel;
/
Create or replace package body personnel as
procedure award_bonuses(empleos_buenos staff_list)is
begin
for i in empleos_buenos.first..empleos_buenos.last
loop
update employees set salary = salary+ 100
where employees.employee_id = empleos_buenos(i);
end loop;
end award_bonuses;
end personnel ;
/
Create or replace package personnel as
type staff_list is table of number;
procedure award_bonuses(empleos_buenos staff_list);
end personnel;
/
Create or replace package body personnel as
procedure award_bonuses(empleos_buenos staff_list)is
begin
for i in empleos_buenos.first..empleos_buenos.last
loop
update employees set salary = salary+ 100
where employees.employee_id = empleos_buenos(i);
end loop;
end award_bonuses;
end personnel ;
/
>>>>>>>>>>>execute personnel.award_bonuses(personnel.staff_list());>>>>>>>>>>>
Example 5-6 : Invoking a Prcedure with a Nested Table Parameter.
----------------------------------------------------------------
Declare
good_employees personnel.staff_list;
begin
good_employees := personnel.staff_list(100, 103, 107);
personnel.award_bonuses(good_employees);
end;
/
<<<<<<<<<
select salary from employees
where employee_id in (100, 103, 107)
/
>>>>>>>>>>
Example 5-7 : Specifying Collection Element Types with %Type and %RowType.
--------------------------------------------------------------------------
declare
Type EmpList is table of employees.employee_id%type;
Type EmpList2 is table of employees%rowtype;
Cursor c1 is select employee_id from employees;
Type Senior_SalesPeople is varray(10) of employees%rowtype;
Cursor c2 is select first_name, last_name from employees;
Type NameList is varray(20) of c2%rowtype;
begin
null;
end;
/
Example 5-8 : Varray of Records.
-------------------------------
Declare
Type name_rec is record(first_name varchar2(20), last_name varchar2(25));
type names is varray(250) of name_rec;
begin
null;
end;
/
<<<<<<<<<<<
Declare
Type name_rec is record(first_name varchar2(20), last_name varchar2(25));
--type names is varray(250) of name_rec;
--a names;
b name_rec;
c name_rec;
begin
b.first_name := 'kamal';
b.last_name := 'jamal';
--a := names(b, c);
dbms_output.put_line(b.first_name);
end;
/
>>>>>>>>>>>>>
Example 5-9 : Not Null Constraint on Collection Elements.
--------------------------------------------------------
Declare
Type EmpList is table of employees.employee_id%type not null;
v_employees EmpList := EmpList (100, 150, 160,200);
begin
dbms_output.put_line(v_employees (3));
end;
/
Example 5-10 : Constructor for a Nested Table.
----------------------------------------------
declare
Type dnames_tab is table of varchar2(30);
dept_names dnames_tab;
begin
dept_names := dnames_tab('Shipping', 'Sales', 'Finance', 'Payroll');
end;
/
Example 5-11 : Constructor for a Varray.
----------------------------------------------
declare
Type dnames_tab is varray(10) of varchar2(30);
dept_names dnames_tab;
begin
dept_names := dnames_tab('Shipping', 'Sales', 'Finance', 'Payroll');
end;
/
Example 5-12 : Collection Constructor Including Null elements.
--------------------------------------------------------------
Declare
type dnames_tab is table of varchar2(30);
Type dnamesNoNulls_type is table of varchar2(3) not null;
dept_names dnames_tab;
begin
dept_names := dnames_tab('Shipping', null, 'Finance', Null);
end;
/
The Following is not allowed:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Declare
type dnames_tab is table of varchar2(30);
Type dnamesNoNulls_type is table of varchar2(30) not null;
dept_names dnamesNoNulls_type;
begin
dept_names := dnamesNoNulls_type ('Shipping', null, 'Finance', null);
end;
/
Example : 5-13 : Combining Collection Declaration and Constructor.
------------------------------------------------------------------
declare
type dnames_tab is table of varchar2(30);
dept_names dnames_tab := dnames_tab('Shipping', 'Sales', 'Finance', 'Payroll');
begin
null;
end;
/
Example 5-14 : Empty Varray Constructor.
----------------------------------------
Declare
Type dnames_var is varray(20) of varchar2(30);
dept_names dnames_var;
begin
if dept_names is null then
dbms_output.put_line('Before Initialization the varray is null.');
--dbms_output.put_line('It has ' ||dept_names.count || ' elements');
else
dbms_output.put_line('Before Initialization the varray is not null.');
end if;
dept_names := dnames_var();
if dept_names is null then
dbms_output.put_line('After Initialization the varray is null.');
dbms_output.put_line('It has ' ||dept_names.count || ' elements');
else
dbms_output.put_line('After Initialization the varray is not null.');
dbms_output.put_line('It has ' ||dept_names.count || ' elements');
end if;
end;
/
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Declare
Type dnames_var is table of varchar2(30);
dept_names dnames_var;
begin
if dept_names is null then
dbms_output.put_line('Before Initialization the varray is null.');
--dbms_output.put_line('It has ' ||dept_names.count || ' elements');
else
dbms_output.put_line('Before Initialization the varray is not null.');
end if;
dept_names := dnames_var();
if dept_names is null then
dbms_output.put_line('After Initialization the varray is null.');
dbms_output.put_line('It has ' ||dept_names.count || ' elements');
else
dbms_output.put_line('After Initialization the varray is not null.');
dbms_output.put_line('It has ' ||dept_names.count || ' elements');
end if;
end;
/
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Example 5-15 : Referencing a Neted Table Element.
-------------------------------------------------
declare
Type Roster is table of varchar2(15);
names Roster := Roster('D Caruso', 'J Hamil', 'D Piro', 'R Singh');
procedure verify_names (the_name varchar2) is
begin
dbms_output.put_line(the_name);
end verify_names;
begin
for i in names.first..names.last loop
if names(i) = 'J Hamil' then
dbms_output.put_line(names(i));
end if;
end loop;
verify_names(names(3));
end;
/
Example 5-16 : Referencing an Element of an Associative Array.
-------------------------------------------------------------=
Declare
Type sum_multiples is table of pls_integer index by pls_integer;
n pls_integer := 2;
sn pls_integer := 20;
m pls_integer := 5;
function get_sum_multiples (multiple in pls_integer, num in pls_integer) return sum_multiples
is
s sum_multiples;
begin
for i in 1..num loop
s(i) := multiple*((i*(i+1))/2);
end loop;
return s;
end get_sum_multiples;
begin
dbms_output.put_line('Sum of the first ' || to_char(n) || ' multiples of '|| to_char(m) || ' is ' || to_char(get_sum_multiples (m, sn)(n)));
end;
/
Example 5-17 : data Type Compatibility for Collection Assignment.
-----------------------------------------------------------------
Declare
type last_name_type is varray (3) of varchar2(64);
Type surname_type is varray(30) of varchar2(42);
group1 last_name_type := last_name_type ('Jones', 'Wong', 'Marceau');
group2 last_name_type := last_name_type ('Klein', 'Patsos', 'Singh');
group3 surname_type := surname_type ('Trevisi', 'Macleod', 'Marquez');
begin
group1 := group2;
--Not allowed becaus they have different data types
-- group2 := group3;
end;
/
Example - 5-18: Assigning a Null value to a Nested Table.
---------------------------------------------------------
Declare
type dnames_tab is table of varchar2(30);
dept_names dnames_tab := dnames_tab('Shipping', 'Sales', 'Finance', 'Payroll');
empty_set dnames_tab;
begin
if
dept_names is not null then
dbms_output.put_line('OK, now dept_names is not null');
end if;
dept_names := empty_set;
if
dept_names is null then
dbms_output.put_line('OK, now dept_names has become null');
end if;
dept_names := dnames_tab('Shipping', 'Sales', 'Finance', 'Payroll');
end;
/
Example 5-19 : Assigning Nested Tables with Set Operators.
----------------------------------------------------------
Declare
Type nested_type is table of number;
nt1 nested_type := nested_type(1, 2, 3);
nt2 nested_type := nested_type(3, 2, 1);
nt3 nested_type := nested_type(2, 3, 1, 3);
nt4 nested_type := nested_type(1, 2, 4);
answer nested_type;
procedure print_nested_table(the_nt nested_type) is
output varchar2(128);
begin
if the_nt is null then
dbms_output.put_line('Results : Null');
return;
end if;
if the_nt.count = 0 then
dbms_output.put_line('Results : Empty Set');
return;
end if;
for i in the_nt.first..the_nt.last loop
output := output|| the_nt(i)|| ' ';
end loop;
dbms_output.put_line('Results : '||output);
end;
begin
answer := nt1 multiset union nt4;
print_nested_table(answer);
answer := nt1 multiset union distinct nt4;
print_nested_table(answer);
answer := nt1 multiset intersect nt4;
print_nested_table(answer);
answer := nt1 multiset intersect distinct nt4;
print_nested_table(answer);
answer := nt1 multiset except nt4;
print_nested_table(answer);
answer := nt1 multiset except distinct nt4;
print_nested_table(answer);
prln('-----------------------------');
answer := nt1 multiset intersect distinct nt4;
print_nested_table(answer);
answer := nt1 multiset union nt3;
print_nested_table(answer);
answer := nt1 multiset union distinct nt4;
print_nested_table(answer);
answer := nt1 multiset intersect nt4;
print_nested_table(answer);
answer := nt1 multiset intersect distinct nt4;
print_nested_table(answer);
answer := set(nt3);
print_nested_table(answer);
end;
/
Example 5-20 : Assigning Values to Varrays with Complex data Types.
------------------------------------------------------------------
Declare
Type emp_name_rec is record(
firstName employees.first_name%type,
lastName employees.last_name%type,
hireDate employees.hire_date%type );
Type EmpList_Arr is varray(10) of emp_name_rec;
SeniorSalespeople EmpList_arr;
Cursor c1 is select first_name, last_name, hire_date from employees;
Type NameSet is table of c1%rowtype;
SeniorTen NameSet;
EndCounter number := 10;
begin
seniorSalespeople := empList_arr();
select first_name, last_name, hire_date bulk collect into seniorTen from employees
where job_id = 'SA_REP'
order by hire_date;
if seniorTen.last > 0 then
if seniorTen.last < 10 then
endCounter := seniorTen.last;
end if;
for i in 1..endcounter loop
seniorSalespeople.extend(1);
seniorSalesPeople(i) := seniorTen(i);
dbms_output.put_line(SeniorSalesPeople(i).lastname||' ---------- ' || seniorSalesPeople(i).firstName||' -------------- '|| seniorsalesPeople(i).hiredate);
end loop;
end if;
end;
/
Example 5-21 : Assigningn Values to Tables with Complex Data Types.
-------------------------------------------------------------------
Declare
Type emp_name_rec is record ( firstName employees.first_name%type, lastName employees.last_name%type, hireDate employees.hire_date%type);
Type EmpList_tab is table of emp_name_rec;
SeniorSalesPeople EmpList_tab;
Cursor c1 is select first_name, last_name, hire_date from employees;
endcounter number := 10;
Type EmpCurType is ref Cursor;
emp_cv EmpCurType;
begin
open emp_cv for select first_name, last_name, hire_date
from employees
where job_id = 'SA_REP' order by hire_date;
fetch emp_cv bulk collect into SeniorSalesPeople;
close emp_cv;
if seniorsalespeople.last > 0 then
if seniorsalespeople.last > 10 then
endcounter := seniorsalespeople.last;
end if;
for i in 1..endcounter loop
prln(seniorsalespeople(i).lastname ||' ========'|| seniorsalespeople(i).firstname||'========'|| seniorsalespeople(i).hiredate);
end loop;
end if;
end;
/
Example 5-22 : Checking if a Collection is null.
------------------------------------------------
Declare
Type emp_name_rec is record(
firstName employees.first_name%type,
lastName employees.last_name%type,
hireDate employees.hire_date%type);
Type staff is table of emp_name_rec;
members staff;
begin
if members is null then
dbms_output.put_line('Null');
else
dbms_output.put_line('Not Null');
end if;
end;
/
Example 5-23 : Coparing Two Nested Tables.
------------------------------------------
Declare
Type dnames_tab is table of varchar2(30);
dept_names1 dnames_tab := dnames_tab('Shipping', 'Sales', 'Finance', 'Payroll');
dept_names2 dnames_tab := dnames_tab('Shipping', 'Sales', 'Finance', 'Payroll');
dept_names3 dnames_tab := dnames_tab('Shipping', 'Sales', 'Finance');
begin
if dept_names1 = dept_names2 then
dbms_output.put_line('dept1 and dept2 have the same members');
else
dbms_output.put_line('dept1 and dept2 have different members');
end if;
if dept_names1 = dept_names3 then
dbms_output.put_line('dept1 and dept2 have the same members');
else
dbms_output.put_line('dept1 and dept3 have different members');
end if;
end;
/
Example 5-24 : Comparing Nested Tables with Set Operators.
----------------------------------------------------------
Declare
Type nested_type is table of number;
nt1 nested_type := nested_type(1, 2, 3);
nt2 nested_type := nested_type(3, 2, 1);
nt3 nested_type := nested_type(2, 3, 1, 3);
nt4 nested_type := nested_type(1, 2, 4);
answer boolean;
howmany number;
procedure testify(truth boolean default null, quantity number default null) is
begin
if
truth is not null then
dbms_output.put_line(Case truth when true then 'True' when false then 'False' end);
end if;
if quantity is not null then
dbms_output.put_line(quantity);
end if;
end;
begin
answer := nt1 in (nt2, nt3, nt4);
testify(truth => answer);
answer := nt1 submultiset of nt3;
testify(truth => answer);
answer := nt1 not submultiset of nt4;
testify(truth => answer);
howmany := cardinality(nt3);
testify (quantity => howmany);
howmany := cardinality(set(nt3));
testify (quantity => howmany);
answer := 4 member of nt1;
testify (truth => answer);
answer:= nt3 is a set;
testify (truth => answer);
answer:= nt3 is not a set;
testify (truth => answer);
answer:= nt1 is empty;
testify (truth => answer);
end;
/
>>>>>>>>>>>Use of Cardinality : Calculate the element of a nested table>>>>>>>>>>>>>>>>>
declare
type a is table of number;
howmany number;
b a := a(1, 2, 3, 4);
begin
howmany := cardinality(b);
dbms_output.put_line(howmany);
end;
/
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Example 5-25 : Multilevel Array.
--------------------------------
Declare
Type t1 is varray(10) of number;
Type nt1 is varray(10) of t1;
va t1 := t1(1, 2, 3);
nva nt1 := nt1 (va, t1(55, 6, 73), t1(2, 4), va);
i integer;
va1 t1;
begin
i := nva (1)(3);
dbms_output.put_line('I = '|| i);
--dbms_output.put_line(nva (5)(1));
dbms_output.put_line('I = '|| i);
nva.extend;
dbms_output.put_line(nva (5)(1));
end;
/
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Declare
Type t1 is varray(10) of number;
Type nt1 is varray(10) of t1;
va t1 := t1(1, 2, 3);
va2 t1 := t1(4, 5, 6);
nva nt1 := nt1(t1(55, 6, 73), t1(2, 4), va2);
begin
null;
end;
/
Example : 5-26 : Multilevel Nested Table.
-----------------------------------------
DECLARE
TYPE tb1 IS TABLE OF VARCHAR2(20);
TYPE Ntb1 IS TABLE OF tb1; -- table of table elements
TYPE Tv1 IS VARRAY(10) OF INTEGER;
TYPE ntb2 IS TABLE OF tv1; -- table of varray elements
vtb1 tb1 := tb1('one', 'three');
vntb1 ntb1 := ntb1(vtb1);
vntb2 ntb2 := ntb2(tv1(3,5), tv1(5,7,3));
-- table of varray elements
BEGIN
vntb1.EXTEND;
vntb1(2) := vntb1(1);
dbms_output.put_line(vntb1(1)(1)||' '||vntb1(1)(2));
-- delete the first element in vntb1
vntb1.DELETE(1);
-- delete the first string
-- from the second table in the nested table
vntb1(2).DELETE(1);
END;
/
>>>>>>>>>my excercise>>>>>>>>>>>>>>>>>
DECLARE
TYPE tb1 IS TABLE OF VARCHAR2(20);
TYPE Ntb1 IS TABLE OF tb1; -- table of table elements
TYPE Tv1 IS VARRAY(10) OF INTEGER;
TYPE ntb2 IS TABLE OF tv1; -- table of varray elements
vtb1 tb1 := tb1('one', 'three');
vntb1 ntb1 := ntb1(vtb1);
vntb2 ntb2 := ntb2(tv1(3,5), tv1(5,7,3));
-- table of varray elements
BEGIN
vntb1.EXTEND;
vntb1(2) := vntb1(1);
dbms_output.put_line(vntb1(1)(1)||' '||vntb1(2)(2));
-- delete the first element in vntb1
vntb1.DELETE(1);
dbms_output.put_line(vntb1(2)(1)||' '||vntb1(2)(2));
-- delete the first string
-- from the second table in the nested table
vntb1(2).DELETE(1);
END;
/
>>>>>>>>>my excercise>>>>>>>>>>>>>>>>>
DECLARE
TYPE tb1 IS TABLE OF VARCHAR2(20);
TYPE Ntb1 IS TABLE OF tb1; -- table of table elements
TYPE Tv1 IS VARRAY(10) OF INTEGER;
TYPE ntb2 IS TABLE OF tv1; -- table of varray elements
vtb1 tb1 := tb1('one', 'three');
vntb1 ntb1 := ntb1(vtb1);
vntb2 ntb2 := ntb2(tv1(3,5), tv1(5,7,3));
-- table of varray elements
BEGIN
vntb1.EXTEND;
vntb1(2) := vntb1(1);
dbms_output.put_line(vntb1(1)(1)||' '||vntb1(2)(2));
-- delete the first element in vntb1
vntb1.DELETE(1);
dbms_output.put_line(vntb1(2)(1)||' '||vntb1(2)(2));
-- delete the first string
-- from the second table in the nested table
vntb1(2).DELETE(1);
dbms_output.put_line(vntb1(2)(2)||' '||vntb1(2)(2));
END;
/
>>>>>>>>>my excercise>>>>>>>>>>>>>>>>>
create procedure prln(obj varchar2) is
begin
dbms_output.put_line(obj);
end;
/
Example 5-27 : Multilevel Associative Array.
-------------------------------------------
Declare
Type tb1 is table of integer index by pls_integer;
Type ntb1 is table of tb1 index by pls_integer;
Type va1 is varray(10) of varchar2(20);
Type ntb2 is table of va1 index by pls_integer;
v1 va1 := va1('hello', 'world');
v2 ntb1;
v3 ntb2;
v4 tb1;
v5 tb1;
begin
v4(1) := 34;
v4(2) := 46456;
v4(456) := 343;
v2(23) := v4;
v3 (34) := va1(33, 456, 656, 343);
v5(1) := 10;
v5(2) := 20;
v2(35) := v5;
--v2(35)(2) := 78;
V2(35) := V4;
prln(v2(35)(2));
prln(v5.count);
end;
/
Example 5-28 : Checking Wheter a Collection Element Exists.
----------------------------------------------------------------------------
Declare
Type NumList is table of Integer;
n NumList := NumList(1, 3, 5, 7);
begin
--n.delete(2);
prln(n(1));
if n.exists(1) then
prln('OK, Element #1 exists! ');
else
prln('OK, Element #1 has been Deleted!');
end if;
if n.exists(2) = false then
prln('OK, Element #2 has been Deleted!');
else
prln(n(2));
end if;
if n.exists(99) = false then
prln('OK, Element #99 does not exists at all! ');
end if;
end;
/
Example 5-29 : Counting Collection Elements with Count.
-----------------------------------------------------------------------
Declare
Type NumList is table of number;
n NumList := NumList (2, 4, 6, 8);
Begin
dbms_output.put_line('There are '|| n.count || ' elements in N.');
n.extend(3); -- Add 3 new elements at the end.
dbms_output.put_line('There are '|| n.count || ' elements in N.');
n := NumList (86, 99, 15);
dbms_output.put_line('There are '|| n.count || ' elements in N.');
n.trim(2);
dbms_output.put_line('There are '|| n.count || ' elements in N.');
end;
/
Example 5-30 : Checking the Maximum Size of a Collection with LIMIT.
------------------------------------------------------------------------------------------
Declare
Type dnames_var is varray(7) of varchar2(30);
dept_names dnames_var := dnames_var('Shipping', 'Sales', 'Finance', 'Payroll');
Begin
prln('dept_names has '|| dept_names.count);
prln('dept_names''s type can hold a maximum of '|| dept_names.limit ||' elements');
prln('The maximum number you can use with '|| ' dept_names.extend() is '|| (dept_names.limit-dept_names.count));
prln(dept_names.first || ' '|| dept_names.last);
end;
/
Example 5-31: Using First and Last with a Collection.
------------------------------------------------------------------
Declare
Type NumList is table of number;
n NumList := NumList (1, 3, 5, 7);
counter integer;
Begin
prln('The first subscript of N is '||n.first);
prln('The last subscript of N is '||n.last);
for i in n.first..n.last loop
prln('Element #' || i || ' = ' || n(i));
end loop;
n.delete(2);
if n is not null then
counter := n.first;
while counter is not null loop
prln('Element # '|| counter || ' = '|| n(counter));
counter := n.next(counter);
end loop;
else
prln('N is null, nothing to do' );
end if;
end;
/
Example 5-32 : Using Prior and Next to Access Collection Elements.
-------------------------------------------------------------------------------------
Declare
Type NumList is table of number;
n NumList := NumList(1966, 1971, 1984, 1989, 1999);
Begin
prln('The element after #2 is #'||n.next(2));
prln('The element before #2 is #'||n.prior(2));
n.delete(3);
prln('The element after #2 is #'||n.next(2));
if n.prior(n.first) is null then
prln('Can''t get Prior of the first element or Next of the Last');
end if;
end;
/
Example 5-33 : Using Next to Access Elements of a Nested Table.
-----------------------------------------------------------------------------------
Declare
Type NumList is table of number;
n NumList
Example 5–34 Using EXTEND to Increase the Size of a Collection
----------------------------------------------------------------------------------
DECLARE
TYPE NumList IS TABLE OF INTEGER;
n NumList := NumList(2,4,6,8);
x NumList := NumList(1,3);
PROCEDURE print_numlist(the_list NumList) IS
output VARCHAR2(128);
BEGIN
FOR i IN the_list.FIRST .. the_list.LAST
LOOP
output :=
output || NVL(TO_CHAR(the_list(i)),'NULL') || ' ';
END LOOP;
DBMS_OUTPUT.PUT_LINE(output);
END;
BEGIN
DBMS_OUTPUT.PUT_LINE
('At first, N has ' || n.COUNT || ' elements.');
n.EXTEND(5); -- Add 5 elements at the end.
DBMS_OUTPUT.PUT_LINE
('Now N has ' || n.COUNT || ' elements.');
-- Elements 5, 6, 7, 8, and 9 are all NULL.
print_numlist(n);
DBMS_OUTPUT.PUT_LINE
('At first, X has ' || x.COUNT || ' elements.');
x.EXTEND(4,2); -- Add 4 elements at the end.
DBMS_OUTPUT.PUT_LINE
('Now X has ' || x.COUNT || ' elements.');
-- Elements 3, 4, 5, and 6 are copies of element #2.
print_numlist(x);
END;
/
Example : 5-35 : Using Trim to Decrease the Size of a Collection.
--------------------------------------------------------------------------------
Declare
Type NumList is table of number;
n NumList := NumList (1, 2, 3, 5, 7, 11);
procedure print_numlist(the_list NumList) is
output varchar2(128);
begin
if
n.count = 0 then
prln('No elements in collection !');
else
for i in the_list.first..the_list.last
loop
output := output|| nvl(to_char(the_list(i)), 'NULL') || ' ' ;
end loop;
prln(output);
end if;
end;
Begin
print_numlist(n);
n.trim(2);
print_numlist(n);
n.trim(n.count);
print_numlist(n);
Begin
n := NumList (1, 2 , 3);
n.trim(100);
Exception
when subscript_beyond_count then
prln('There are not 100 elemnts to trim');
n := NumList(1, 2, 3, 4);
n.delete(3);
n.trim(2);
print_numList(n);
end;
end;
/
Example 5-36 : Using Trim on Deleted Elements.
-----------------------------------------------------------
Declare
Type CourseList is table of Varchar2(10);
Courses CourseList;
Begin
Courses := CourseList('Biol 4412', 'Psych 3112', 'Anth 3001');
prln( courses.last);
courses.delete(courses.last);
prln(courses.last);
courses.trim(courses.count);
prln(courses(courses.count));
prln(courses(1));
end;
/
Example 5-37 : Using the Delete Method on a Collection.
----------------------------------------------------------------------
Declare
Type NumList is table of number;
n NumList := NumList(10, 20, 30, 40, 50, 60, 70, 80, 90, 100);
Type NickList is table of Varchar2(64) index by varchar2(21);
nickNames NickList;
Begin
n.delete(2);
n.delete(3, 6); -- deletes elements 3 through 6
n.delete(7, 7);
n.delete(6, 3); -- does nothing since 6 > 3
n.delete; -- delete all elements.
nicknames('Bob') := 'Robert';
nicknames('Buffy') := 'Esmerelda';
nicknames('Chip') := 'Charles';
nicknames('Dan') := 'Daniel';
nicknames('Fluffy') := 'Ernestina';
nicknames('Rob') := 'Robert';
nicknames('Dan') := 'Daniel';
prln(nicknames.count);
nicknames.delete('Chip');
prln(nicknames.count);
nicknames.delete;
prln(nicknames.count);
end;
/
Example 5-38 : Collection Exception.
----------------------------------------------
Declare
Type WordList is table of varchar2(5);
Words WordList;
err_msg varchar2(100);
procedure display_error is
Begin
err_msg := substr(sqlerrm, 1, 100);
prln('Error Message = ' || err_msg);
End;
Begin
Begin
words(1) := 10;
Exception
When others then display_error;
end;
words := wordList('1st', '2nd', '3rd');
words(3) := words(1)||'+2';
Begin
words(3) := 'Longer than 5 characters';
exception
when others then display_error;
end;
Begin
words('B') := 'dunno';
exception
when others then display_error;
end;
Begin
words(0) := 'zero';
exception
when others then display_error;
end;
Begin
words(4) := 'maybe';
exception
when others then display_error;
end;
Begin
words.delete(1);
if words(1) = 'First' then NULL;
end if;
exception
when others then display_error;
End;
end;
/
Example 5-39 : How Invalid Subscript are Handled with Delete(n).
----------------------------------------------------------------------------------
Declare
Type NumList is table of number;
nums NumList := NumList(10, 20, 30);
Begin
nums.delete(-1);
nums.delete(3);
nums(3) := 30;
prln(nums.count);
End;
/
Example 5-40 : Incompatibility Between Package and Local Collection Types.
------------------------------------------------------------------------------------------------
Create package pkg as
Type NumList is table of Number;
procedure print_numlist(nums NumList);
end pkg;
/
Create or replace package body pkg as
procedure print_numlist(nums NumList) is
Begin
for i in nums.first..nums.last loop
prln(nums(i));
end loop;
end;
end pkg;
/
Declare
Type NumList is table of number;
n1 pkg.NumList := pkg.NumList(2, 4);
n2 NumList := NumList(6, 8);
Begin
pkg.print_numlist(n1);
--pkg.print_numlist(n2); -- not allowed
end;
/
Example 5-41 : Declaring and Initializing a Simple Record.
-----------------------------------------------------------------------
Declare
Type DeptRecTyp is record(
deptid number (4) not null := 99,
dname departments.department_NAME%type,
loc departments.location_id%type,
region regions%rowtype
);
Dept_Rec DeptRecTyp;
BEGIN
dept_rec.dname := 'PURCHASING';
END;
/
Example 5-42 : Declaring and Initializing RECORD Types.
------------------------------------------------------
DECLARE
Type rec1_t is record (
field1 varchar2(16),
field2 number,
field3 DATE);
Type rec2_t is record (
id integer not null := -1,
name varchar2(64) not null := '[anonymous]'
);
rec1 rec1_t;
rec2 rec2_t;
rec3 employees%rowtype;
Type rec4_t is record (first_name employees.first_name%type,
last_name employees.last_name%type,
rating number
);
rec4 rec4_t;
BEGIN
rec1.field1 := 'Yesterday';
rec1.field2 := 60;
rec1.field3 := trunc(sysdate-1);
prln(rec2.name);
END;
/
Example 5-43 : Using %ROWTYPE to Declare a Record.
-----------------------------------------------------------------------
Declare
Cursor c1 is
select department_id, department_name, location_id
from departments;
rec1 c1%rowtype;
Type DeptRec2 is Record (dept_id departments.department_id%type,
dept_name departments.department_name%type,
dept_loc departments.location_id%type);
rec2 DeptRec2;
Type DeptRec3 is record(
dept_id number,
dept_name varchar2(14),
dept_loc varchar2(13)
);
rec3 DeptRec3;
Begin
null;
end;
/
Example 5-44 : Returning a Record from a Function.
-----------------------------------------------------------------
Declare
Type EmpRecTyp is Record(
emp_id number(6),
salary number(8, 2)
);
Cursor desc_salary return EmpRecTyp is
select employee_id, salary
from employees
order by salary desc;
emp_rec EmpRecTyp;
Function nth_highest_salary(n integer) return EmpRecTyp is
Begin
open desc_salary;
for i in 1..n loop
fetch desc_salary into emp_rec;
end loop;
return emp_rec;
end nth_highest_salary;
Begin
null;
end;
/
>>>>>>>>>>>>>>>>>>>>>>>>>>>
Declare
a number;
b number;
function
mysum(x number, y number) return number is
begin
return x*y;
end mysum;
Begin
prln(mysum(2, 15));
end;
/
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Example 5-45 : Using a Record as Parameter to a Procedure.
---------------------------------------------------------------------------
Declare
Type EmpRecTyp is Record( emp_id number (6), emp_sal number(8, 2));
Procedure raise_salary (emp_info EmpRecTyp) is
Begin
update employees set salary = salary+ salary* .10
where employee_id = emp_info.emp_id;
end raise_salary;
Begin
null;
end;
/
Example 5-46 : Declaring a Nested Record.
-----------------------------------------------------
Declare
Type TimeTyp is record(minutes smallint, hours smallint);
Type meetingTyp is record(day date, time_of Timetyp, dept departments%rowtype, place varchar2(20), purpose varchar2(50));
meeting meetingTyp;
seminar meetingTyp;
Begin
seminar.time_of := meeting.time_of;
end;
/
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Declare
Type TimeTyp is record(minutes smallint, hours smallint);
Type meetingTyp is record(day date, time_of Timetyp, dept departments%rowtype, place varchar2(20), purpose varchar2(50));
meeting meetingTyp;
seminar meetingTyp;
Begin
meeting.day := '01-JUN-15';
seminar.time_of := meeting.time_of;
end;
/
Example 5-47 : Assigning Default values to a record.
----------------------------------------------------------------
declare
type recordType is record(field1 number, field2 varchar2(32) default 'something');
rec1 recordType;
rec2 recordType;
begin
rec1.field1 := 100;
rec1.field2 := 'something else';
rec2.field1 := 200;
rec1 := rec2;
dbms_output.put_line(rec1.field1 ||' ' || rec1.field2);
end;
/
Example 5-48 : Assigning all the fields of a record in one statement.
---------------------------------------------------------------------
declare
type DeptRec1 is record (dept_num number(2), dept_name varchar2(14));
type DeptRec2 is record (dept_num number(2), dept_name varchar2(14));
dept1_info deptRec1;
dept2_info deptRec2;
dept3_info deptRec2;
begin
--dept1_info := dept2_info;
dept3_info.dept_num := 10;
dept3_info.dept_name := 'Admin';
dept2_info := dept3_info;
dbms_output.put_line('Department Id is '|| dept2_info.dept_num);
end;
/
------------------------------------------------------------------------
declare
type recordtype is record (last employees.last_name%type, id employees.employee_id%type);
cursor c1 is select last_name, employee_id from employees;
rec1 recordType;
rec2 c1%rowtype;
begin
select last_name, employee_id into rec2 from employees
where rownum <2;
rec1 := rec2;
dbms_output.put_line(rec1.last);
end;
/
---------------------------------------------------------------------------
declare
cursor c1 is select last_name from employees;
begin
for item in c1 loop
dbms_output.put_line(item.last_name);
end loop;
end;
/
Example : 5-49 Using select itno to assign values in a Record.
----------------------------------------------------------------------------
declare
type recordType is record(last employees.last_name%type, id employees.employee_id%type);
rec1 recordType;
begin
select last_name, employee_id into rec1 from employees where rownum <2;
dbms_output.put_line('employee '|| rec1.id);
end;
/
declare
type recordType is record(last employees.last_name%type, id employees.employee_id%type);
rec1 recordType;
begin
select last_name, employee_id into rec1 from employees where rownum <2;
dbms_output.put_line('employee id : '|| rec1.id);
dbms_output.put_line('employee name : '|| rec1.last);
end;
/
--------------------------
declare
cursor c1 is select employee_id, last_name from employees order by employee_id;
v1 c1%rowtype;
begin
open c1;
fetch c1 into v1;
dbms_output.put_line(v1.employee_id ||' '||v1.last_name );
end;
/
Example 5-50 : Insertig a PL/SQL Record Using %Rowtype
---------------------------------------------------------------------------
declare
dept_info departments%rowtype;
begin
dept_info.department_id := 300;
dept_info.department_name := 'Personnel';
dept_info.location_id := 1700;
insert into departments values dept_info;
end;
/
Example 5-51 : Updating a Row Using a Record
--------------------------------------------------------------------------
declare
dept_info departments%rowtype;
begin
dept_info.department_id := 300;
dept_info.department_name := 'Personnel2';
dept_info.location_id := 1700;
update departments set row = dept_info
where department_id = 300;
end;
/
Example 5-52 : Using the Returning Into Clause with a Record.
---------------------------------------------------------------------------
Declare
type EmpRec is record (last_name employees.last_name%type, salary employees.salary%type, commission_pct employees.commission_pct%type);
emp_info EmpRec;
emp_id number := 100;
begin
update employees set salary = salary* nvl(commission_pct, 1)
where employee_id = emp_id
returning last_name, salary, commission_pct into emp_info;
dbms_output.put_line('Just gave a raise to '|| emp_info.last_name || ' who now makes '|| emp_info.salary);
rollback;
end;
/
---------------------------------------------------------------------------------
Declare
type EmpRec is record (last_name employees.last_name%type, salary employees.salary%type, commission_pct employees.commission_pct%type);
emp_info EmpRec;
emp_id number := 101;
begin
delete from emp
where employee_id = emp_id
returning last_name, salary, commission_pct into emp_info;
dbms_output.put_line('Just gave a raise to '|| emp_info.last_name || ' who now makes '|| emp_info.salary);
rollback;
end;
/
Example 5-53 : Using Bulk Collect with Selectr into statement.
-------------------------------------------------------------
Declare
Type employeeSet is table of employees%rowtype;
underPaid employeeSet;
Cursor c1 is select first_name, last_name from employees;
type NameSet is table of c1%rowtype;
some_names NameSet;
begin
select * bulk collect into underPaid from employees
where salary < 5000 order by salary desc;
dbms_output.put_line(underPaid.count|| ' people make less than 5000');
for i in underPaid.first..underPaid.last loop
dbms_output.put_line(underpaid(i).last_name || ' makes '|| underPaid(i).salary || ' '||underPaid(i).department_id);
end loop;
select first_name, last_name bulk collect into some_names from employees where rownum < 11;
for i in some_names.first..some_names.last loop
dbms_output.put_line(some_names(i).first_name ||' ' || some_names(i).last_name);
end loop;
end;
/
>>>>>>>>>>>>excercise>>>>>>>>>>
declare
a departments%rowtype;
begin
a.department_id := 100;
dbms_output.put_line(a.department_id);
end;
/
Creating Object
--------------------
CREATE OR REPLACE TYPE CUSTOMER_TYP_DEMO AS OBJECT (
CUSTOMER_ID NUMBER(6),
CUST_FIRST_NAME VARCHAR2(2),
CUST_LAST_NAME VARCHAR2(20),
CUST_ADDRESS CUST_ADDRESS_TYP,
PHONE_NUMBERS PHONE_LIST_TYP,
NLS_LANGUAGE VARCHAR2(30),
CREDIT_LIMIT NUMBER(30),
CUST_EMAIL VARCHAR2(30),
CUST_ORDERS ORDER_LIST_TYP
);
/
CREATE OR REPLACE TYPE ASS AS TABLE OF CUSTOMER_TYP_DEMO;
/
CREATE TYPE DATA_TYP1 AS OBJECT (YEAR NUMBER, MEMBER FUNCTION PROD (INVENT NUMBER) RETURN NUMBER);
/
CREATE TYPE BODY DATA_TYP1 IS
MEMBER FUNCTION PROD(INVENT NUMBER) RETURN NUMBER IS
BEGIN
RETURN (YEAR + INVENT);
END;
END;
/
CREATE TYPE CORPORATE_CUSTOMER_TYP_DEMO UNDER CUSTOMER_TYP (ACCOUNT_MGR_ID NUMBER(6));
/
CREATE or replace TYPE address_t AS OBJECT
EXTERNAL NAME 'Examples.Address' LANGUAGE JAVA
USING SQLData(
STREET_ATTR VARCHAR (250) EXTERNAL NAME 'STREET',
CITTY_ATTR VARCHAR(250) EXTERNAL NAME 'CITY',
STATE VARCHAR(50) EXTERNAL NAME 'STATE',
ZIP_CODE_ATTR NUMBER EXTERNAL NAME 'ZIPCODE',
STATIC FUNCTION recom_width RETURN NUMBER
EXTERNAL VARIABLE NAME 'recommendedWidth',
STATIC FUNCTION create_address RETURN address_t
EXTERNAL NAME 'create() return Examples.Address',
STATIC FUNCTION construct RETURN address_t
EXTERNAL NAME 'create() return Examples.Address',
STATIC FUNCTION create_address (street VARCHAR, city VARCHAR, state VARCHAR, zip NUMBER) RETURN address_t
EXTERNAL NAME 'create (java.lang.String, java.lang.String, java.lang.String, int ) return Examples.Address',
STATIC FUNCTION construct (street VARCHAR, city VARCHAR, state VARCHAR, zip NUMBER) RETURN address_t
EXTERNAL NAME 'create (java.lang.String, java.lang.String, java.lang.String, int ) return Examples.Address',
MEMBER FUNCTION to_string RETURN VARCHAR
EXTERNAL NAME 'tojava.lang.String() return java.lang.String',
MEMBER FUNCTION strip RETURN SELF AS RESULT
EXTERNAL NAME 'removeLeadingBlanks() return Examples.Address'
) NOT FINAL;
/
Create type my_type as object
external name 'Examples.Address' language java
using SQLData (myName varchar(25) external name 'myName') not final;
/
Create type my_type2 as object
external name 'Examples' language java
using SQLData (myName varchar(25) external name 'myName') not final;
/
Create type my_type3 as object
external name 'EX' language java
using SQLData (myName varchar(25) external name 'myName') not final;
/
Create or replace Type long_address_t
under address_t
external Name 'Examples.LongAddress' Language Java
Using SQLData(
street2_attr varchar(250) external name 'street2',
country_attr varchar(250) external name 'country',
address_code_attr varchar(50) external name 'addrcode',
static function create_address return long_address_t
external name 'create () return Examples.LongAddress',
static function construct (street varchar, city varchar, state varchar, country varchar, addrs_cd varchar) return long_address_t
external name 'create (java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) return Examples.LongAddress',
static function construct return long_address_t
external name 'Examples.LongAddress() return Examples.LongAddress',
Static function create_longaddress(street varchar, city varchar, state varchar, country varchar, addrs_cd varchar) return long_address_t
external name 'Examples.LongAddress(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String ) return Examples.LongAddress',
member function get_country return varchar
external name 'country_with_code () return java.lang.String'
);
/
Create type person_t as object (name varchar2(100), ssn number) not final;
/
Create type employee_t under person_t (department_id number, salary number) not final;
/
Create type part_time_emp_t under employee_t (num_hrs number);
/
Create type textdoc_typ as object (document_typ varchar2(32), formatted_doc blob);
/
Create type phone_list_typ_demo as varray(5) of varchar2(25);
/
Create type textdoc_tab as table of textdoc_typ;
/
create type cust_address_typ2 as object (
street_address varchar2(40),
postal_code varchar2(10),
city varchar2(30),
state_province varchar2(10),
country_id char(2),
phone phone_list_typ
);
/
create type cust_nt_address_typ as table of cust_address_typ2;
/
CREATE TYPE DEMO_TYP1 AS OBJECT (X NUMBER, Y NUMBER);
/
CREATE TABLE DEMO_TAB1 (B1 NUMBER, B2 DEMO_TYP1);
/
INSERT INTO DEMO_TAB1 VALUES (1, DEMO_TYP1(2, 3));
/
CREATE OR REPLACE TYPE DEMO_TYP2 AS OBJECT (A1 NUMBER, MEMBER FUNCTION GET_SQUARE RETURN NUMBER);
/
CREATE TABLE DEMO_TAB2 (COL DEMO_TYP2);
/
CREATE OR REPLACE TYPE BODY DEMO_TYP2 IS
MEMBER FUNCTION GET_SQUARE
RETURN NUMBER
IS X NUMBER;
BEGIN
SELECT C.COL.A1 * C.COL.A1 INTO X FROM DEMO_TAB2 C;
RETURN (X);
END;
END;
/
Example 5-1 : Declaring and Using an Associative Array.
----------------------------------------------------------------------
declare
type population is table of number index by varchar2(64);
city_population population;
i varchar2(64);
begin
city_population('SallVille') := 2000;
city_population('MidLand') := 750000;
city_population('Megaloplis') := 1000000;
i := city_population.first;
while i is not null loop
dbms_output.put_line('Population of '|| i || ' is ' || to_char(city_population(i)));
i := city_population.next(i);
end loop;
end;
/
Example 5-2 : Declaring an Associative Array.
--------------------------------------------------------
declare
type emptabtype is table of employees%rowtype index by pls_integer;
emp_tab emptabtype;
begin
select * into emp_tab(100) from employees where employee_id = 100;
end;
/
Example 5-3 : Declaring Nested Tables, Varrays and Associative Arrays.
----------------------------------------------------------------------------------------
declare
type nested_type is table of varchar2(30);
type nested_type2 is table of number;
type varray_type is varray(5) of integer;
type assoc_array_num_type is table of number index by pls_integer;
type assoc_array_str_type is table of varchar2(32) index by pls_integer;
type assoc_array_str_type2 is table of varchar2(32) index by varchar2(64);
v1 nested_type;
v2 varray_type;
v3 assoc_array_num_type;
v4 assoc_array_str_type;
v5 assoc_array_str_type2;
v6 nested_type2;
begin
v1 := nested_type('Shipping', 'Sales', 'Finance', 'Payroll');
v2 := varray_type(1, 2, 3, 4, 5);
v3(99) := 10;
v3(7) := 100;
v4(42) := 'Smith';
v4(54) := 'Johes';
v5('Canada') := 'North America';
v5('Greece') := 'Europe';
v6 := nested_type2(10, 20, 30, 40, 50);
dbms_output.put_line(v6(2));
end;
/
Example 5-4 : Declaring Collection with %Type;
------------------------------------------------------------
declare
type few_depts is varray(10) of varchar2(30);
type many_depts is varray(10) of varchar2(64);
some_depts few_depts;
local_depts some_depts%type;
globale_depts some_depts%type;
begin
local_depts := few_depts('ad', 'man', 'hr');
dbms_output.put_line(local_depts(1));
end;
/
Example 5-5 : Declaring a Procedure Parameter as a Nested Table.
---------------------------------------------------------------
Create or replace package personnel as
type staff_list is table of employees.employee_id%type;
procedure award_bonuses(empleos_buenos staff_list);
end personnel;
/
Create or replace package body personnel as
procedure award_bonuses(empleos_buenos staff_list)is
begin
for i in empleos_buenos.first..empleos_buenos.last
loop
update employees set salary = salary+ 100
where employees.employee_id = empleos_buenos(i);
end loop;
end award_bonuses;
end personnel ;
/
Create or replace package personnel as
type staff_list is table of number;
procedure award_bonuses(empleos_buenos staff_list);
end personnel;
/
Create or replace package body personnel as
procedure award_bonuses(empleos_buenos staff_list)is
begin
for i in empleos_buenos.first..empleos_buenos.last
loop
update employees set salary = salary+ 100
where employees.employee_id = empleos_buenos(i);
end loop;
end award_bonuses;
end personnel ;
/
>>>>>>>>>>>execute personnel.award_bonuses(personnel.staff_list());>>>>>>>>>>>
Example 5-6 : Invoking a Prcedure with a Nested Table Parameter.
----------------------------------------------------------------
Declare
good_employees personnel.staff_list;
begin
good_employees := personnel.staff_list(100, 103, 107);
personnel.award_bonuses(good_employees);
end;
/
<<<<<<<<<
select salary from employees
where employee_id in (100, 103, 107)
/
>>>>>>>>>>
Example 5-7 : Specifying Collection Element Types with %Type and %RowType.
--------------------------------------------------------------------------
declare
Type EmpList is table of employees.employee_id%type;
Type EmpList2 is table of employees%rowtype;
Cursor c1 is select employee_id from employees;
Type Senior_SalesPeople is varray(10) of employees%rowtype;
Cursor c2 is select first_name, last_name from employees;
Type NameList is varray(20) of c2%rowtype;
begin
null;
end;
/
Example 5-8 : Varray of Records.
-------------------------------
Declare
Type name_rec is record(first_name varchar2(20), last_name varchar2(25));
type names is varray(250) of name_rec;
begin
null;
end;
/
<<<<<<<<<<<
Declare
Type name_rec is record(first_name varchar2(20), last_name varchar2(25));
--type names is varray(250) of name_rec;
--a names;
b name_rec;
c name_rec;
begin
b.first_name := 'kamal';
b.last_name := 'jamal';
--a := names(b, c);
dbms_output.put_line(b.first_name);
end;
/
>>>>>>>>>>>>>
Example 5-9 : Not Null Constraint on Collection Elements.
--------------------------------------------------------
Declare
Type EmpList is table of employees.employee_id%type not null;
v_employees EmpList := EmpList (100, 150, 160,200);
begin
dbms_output.put_line(v_employees (3));
end;
/
Example 5-10 : Constructor for a Nested Table.
----------------------------------------------
declare
Type dnames_tab is table of varchar2(30);
dept_names dnames_tab;
begin
dept_names := dnames_tab('Shipping', 'Sales', 'Finance', 'Payroll');
end;
/
Example 5-11 : Constructor for a Varray.
----------------------------------------------
declare
Type dnames_tab is varray(10) of varchar2(30);
dept_names dnames_tab;
begin
dept_names := dnames_tab('Shipping', 'Sales', 'Finance', 'Payroll');
end;
/
Example 5-12 : Collection Constructor Including Null elements.
--------------------------------------------------------------
Declare
type dnames_tab is table of varchar2(30);
Type dnamesNoNulls_type is table of varchar2(3) not null;
dept_names dnames_tab;
begin
dept_names := dnames_tab('Shipping', null, 'Finance', Null);
end;
/
The Following is not allowed:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Declare
type dnames_tab is table of varchar2(30);
Type dnamesNoNulls_type is table of varchar2(30) not null;
dept_names dnamesNoNulls_type;
begin
dept_names := dnamesNoNulls_type ('Shipping', null, 'Finance', null);
end;
/
Example : 5-13 : Combining Collection Declaration and Constructor.
------------------------------------------------------------------
declare
type dnames_tab is table of varchar2(30);
dept_names dnames_tab := dnames_tab('Shipping', 'Sales', 'Finance', 'Payroll');
begin
null;
end;
/
Example 5-14 : Empty Varray Constructor.
----------------------------------------
Declare
Type dnames_var is varray(20) of varchar2(30);
dept_names dnames_var;
begin
if dept_names is null then
dbms_output.put_line('Before Initialization the varray is null.');
--dbms_output.put_line('It has ' ||dept_names.count || ' elements');
else
dbms_output.put_line('Before Initialization the varray is not null.');
end if;
dept_names := dnames_var();
if dept_names is null then
dbms_output.put_line('After Initialization the varray is null.');
dbms_output.put_line('It has ' ||dept_names.count || ' elements');
else
dbms_output.put_line('After Initialization the varray is not null.');
dbms_output.put_line('It has ' ||dept_names.count || ' elements');
end if;
end;
/
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Declare
Type dnames_var is table of varchar2(30);
dept_names dnames_var;
begin
if dept_names is null then
dbms_output.put_line('Before Initialization the varray is null.');
--dbms_output.put_line('It has ' ||dept_names.count || ' elements');
else
dbms_output.put_line('Before Initialization the varray is not null.');
end if;
dept_names := dnames_var();
if dept_names is null then
dbms_output.put_line('After Initialization the varray is null.');
dbms_output.put_line('It has ' ||dept_names.count || ' elements');
else
dbms_output.put_line('After Initialization the varray is not null.');
dbms_output.put_line('It has ' ||dept_names.count || ' elements');
end if;
end;
/
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Example 5-15 : Referencing a Neted Table Element.
-------------------------------------------------
declare
Type Roster is table of varchar2(15);
names Roster := Roster('D Caruso', 'J Hamil', 'D Piro', 'R Singh');
procedure verify_names (the_name varchar2) is
begin
dbms_output.put_line(the_name);
end verify_names;
begin
for i in names.first..names.last loop
if names(i) = 'J Hamil' then
dbms_output.put_line(names(i));
end if;
end loop;
verify_names(names(3));
end;
/
Example 5-16 : Referencing an Element of an Associative Array.
-------------------------------------------------------------=
Declare
Type sum_multiples is table of pls_integer index by pls_integer;
n pls_integer := 2;
sn pls_integer := 20;
m pls_integer := 5;
function get_sum_multiples (multiple in pls_integer, num in pls_integer) return sum_multiples
is
s sum_multiples;
begin
for i in 1..num loop
s(i) := multiple*((i*(i+1))/2);
end loop;
return s;
end get_sum_multiples;
begin
dbms_output.put_line('Sum of the first ' || to_char(n) || ' multiples of '|| to_char(m) || ' is ' || to_char(get_sum_multiples (m, sn)(n)));
end;
/
Example 5-17 : data Type Compatibility for Collection Assignment.
-----------------------------------------------------------------
Declare
type last_name_type is varray (3) of varchar2(64);
Type surname_type is varray(30) of varchar2(42);
group1 last_name_type := last_name_type ('Jones', 'Wong', 'Marceau');
group2 last_name_type := last_name_type ('Klein', 'Patsos', 'Singh');
group3 surname_type := surname_type ('Trevisi', 'Macleod', 'Marquez');
begin
group1 := group2;
--Not allowed becaus they have different data types
-- group2 := group3;
end;
/
Example - 5-18: Assigning a Null value to a Nested Table.
---------------------------------------------------------
Declare
type dnames_tab is table of varchar2(30);
dept_names dnames_tab := dnames_tab('Shipping', 'Sales', 'Finance', 'Payroll');
empty_set dnames_tab;
begin
if
dept_names is not null then
dbms_output.put_line('OK, now dept_names is not null');
end if;
dept_names := empty_set;
if
dept_names is null then
dbms_output.put_line('OK, now dept_names has become null');
end if;
dept_names := dnames_tab('Shipping', 'Sales', 'Finance', 'Payroll');
end;
/
Example 5-19 : Assigning Nested Tables with Set Operators.
----------------------------------------------------------
Declare
Type nested_type is table of number;
nt1 nested_type := nested_type(1, 2, 3);
nt2 nested_type := nested_type(3, 2, 1);
nt3 nested_type := nested_type(2, 3, 1, 3);
nt4 nested_type := nested_type(1, 2, 4);
answer nested_type;
procedure print_nested_table(the_nt nested_type) is
output varchar2(128);
begin
if the_nt is null then
dbms_output.put_line('Results : Null');
return;
end if;
if the_nt.count = 0 then
dbms_output.put_line('Results : Empty Set');
return;
end if;
for i in the_nt.first..the_nt.last loop
output := output|| the_nt(i)|| ' ';
end loop;
dbms_output.put_line('Results : '||output);
end;
begin
answer := nt1 multiset union nt4;
print_nested_table(answer);
answer := nt1 multiset union distinct nt4;
print_nested_table(answer);
answer := nt1 multiset intersect nt4;
print_nested_table(answer);
answer := nt1 multiset intersect distinct nt4;
print_nested_table(answer);
answer := nt1 multiset except nt4;
print_nested_table(answer);
answer := nt1 multiset except distinct nt4;
print_nested_table(answer);
prln('-----------------------------');
answer := nt1 multiset intersect distinct nt4;
print_nested_table(answer);
answer := nt1 multiset union nt3;
print_nested_table(answer);
answer := nt1 multiset union distinct nt4;
print_nested_table(answer);
answer := nt1 multiset intersect nt4;
print_nested_table(answer);
answer := nt1 multiset intersect distinct nt4;
print_nested_table(answer);
answer := set(nt3);
print_nested_table(answer);
end;
/
Example 5-20 : Assigning Values to Varrays with Complex data Types.
------------------------------------------------------------------
Declare
Type emp_name_rec is record(
firstName employees.first_name%type,
lastName employees.last_name%type,
hireDate employees.hire_date%type );
Type EmpList_Arr is varray(10) of emp_name_rec;
SeniorSalespeople EmpList_arr;
Cursor c1 is select first_name, last_name, hire_date from employees;
Type NameSet is table of c1%rowtype;
SeniorTen NameSet;
EndCounter number := 10;
begin
seniorSalespeople := empList_arr();
select first_name, last_name, hire_date bulk collect into seniorTen from employees
where job_id = 'SA_REP'
order by hire_date;
if seniorTen.last > 0 then
if seniorTen.last < 10 then
endCounter := seniorTen.last;
end if;
for i in 1..endcounter loop
seniorSalespeople.extend(1);
seniorSalesPeople(i) := seniorTen(i);
dbms_output.put_line(SeniorSalesPeople(i).lastname||' ---------- ' || seniorSalesPeople(i).firstName||' -------------- '|| seniorsalesPeople(i).hiredate);
end loop;
end if;
end;
/
Example 5-21 : Assigningn Values to Tables with Complex Data Types.
-------------------------------------------------------------------
Declare
Type emp_name_rec is record ( firstName employees.first_name%type, lastName employees.last_name%type, hireDate employees.hire_date%type);
Type EmpList_tab is table of emp_name_rec;
SeniorSalesPeople EmpList_tab;
Cursor c1 is select first_name, last_name, hire_date from employees;
endcounter number := 10;
Type EmpCurType is ref Cursor;
emp_cv EmpCurType;
begin
open emp_cv for select first_name, last_name, hire_date
from employees
where job_id = 'SA_REP' order by hire_date;
fetch emp_cv bulk collect into SeniorSalesPeople;
close emp_cv;
if seniorsalespeople.last > 0 then
if seniorsalespeople.last > 10 then
endcounter := seniorsalespeople.last;
end if;
for i in 1..endcounter loop
prln(seniorsalespeople(i).lastname ||' ========'|| seniorsalespeople(i).firstname||'========'|| seniorsalespeople(i).hiredate);
end loop;
end if;
end;
/
Example 5-22 : Checking if a Collection is null.
------------------------------------------------
Declare
Type emp_name_rec is record(
firstName employees.first_name%type,
lastName employees.last_name%type,
hireDate employees.hire_date%type);
Type staff is table of emp_name_rec;
members staff;
begin
if members is null then
dbms_output.put_line('Null');
else
dbms_output.put_line('Not Null');
end if;
end;
/
Example 5-23 : Coparing Two Nested Tables.
------------------------------------------
Declare
Type dnames_tab is table of varchar2(30);
dept_names1 dnames_tab := dnames_tab('Shipping', 'Sales', 'Finance', 'Payroll');
dept_names2 dnames_tab := dnames_tab('Shipping', 'Sales', 'Finance', 'Payroll');
dept_names3 dnames_tab := dnames_tab('Shipping', 'Sales', 'Finance');
begin
if dept_names1 = dept_names2 then
dbms_output.put_line('dept1 and dept2 have the same members');
else
dbms_output.put_line('dept1 and dept2 have different members');
end if;
if dept_names1 = dept_names3 then
dbms_output.put_line('dept1 and dept2 have the same members');
else
dbms_output.put_line('dept1 and dept3 have different members');
end if;
end;
/
Example 5-24 : Comparing Nested Tables with Set Operators.
----------------------------------------------------------
Declare
Type nested_type is table of number;
nt1 nested_type := nested_type(1, 2, 3);
nt2 nested_type := nested_type(3, 2, 1);
nt3 nested_type := nested_type(2, 3, 1, 3);
nt4 nested_type := nested_type(1, 2, 4);
answer boolean;
howmany number;
procedure testify(truth boolean default null, quantity number default null) is
begin
if
truth is not null then
dbms_output.put_line(Case truth when true then 'True' when false then 'False' end);
end if;
if quantity is not null then
dbms_output.put_line(quantity);
end if;
end;
begin
answer := nt1 in (nt2, nt3, nt4);
testify(truth => answer);
answer := nt1 submultiset of nt3;
testify(truth => answer);
answer := nt1 not submultiset of nt4;
testify(truth => answer);
howmany := cardinality(nt3);
testify (quantity => howmany);
howmany := cardinality(set(nt3));
testify (quantity => howmany);
answer := 4 member of nt1;
testify (truth => answer);
answer:= nt3 is a set;
testify (truth => answer);
answer:= nt3 is not a set;
testify (truth => answer);
answer:= nt1 is empty;
testify (truth => answer);
end;
/
>>>>>>>>>>>Use of Cardinality : Calculate the element of a nested table>>>>>>>>>>>>>>>>>
declare
type a is table of number;
howmany number;
b a := a(1, 2, 3, 4);
begin
howmany := cardinality(b);
dbms_output.put_line(howmany);
end;
/
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Example 5-25 : Multilevel Array.
--------------------------------
Declare
Type t1 is varray(10) of number;
Type nt1 is varray(10) of t1;
va t1 := t1(1, 2, 3);
nva nt1 := nt1 (va, t1(55, 6, 73), t1(2, 4), va);
i integer;
va1 t1;
begin
i := nva (1)(3);
dbms_output.put_line('I = '|| i);
--dbms_output.put_line(nva (5)(1));
dbms_output.put_line('I = '|| i);
nva.extend;
dbms_output.put_line(nva (5)(1));
end;
/
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Declare
Type t1 is varray(10) of number;
Type nt1 is varray(10) of t1;
va t1 := t1(1, 2, 3);
va2 t1 := t1(4, 5, 6);
nva nt1 := nt1(t1(55, 6, 73), t1(2, 4), va2);
begin
null;
end;
/
Example : 5-26 : Multilevel Nested Table.
-----------------------------------------
DECLARE
TYPE tb1 IS TABLE OF VARCHAR2(20);
TYPE Ntb1 IS TABLE OF tb1; -- table of table elements
TYPE Tv1 IS VARRAY(10) OF INTEGER;
TYPE ntb2 IS TABLE OF tv1; -- table of varray elements
vtb1 tb1 := tb1('one', 'three');
vntb1 ntb1 := ntb1(vtb1);
vntb2 ntb2 := ntb2(tv1(3,5), tv1(5,7,3));
-- table of varray elements
BEGIN
vntb1.EXTEND;
vntb1(2) := vntb1(1);
dbms_output.put_line(vntb1(1)(1)||' '||vntb1(1)(2));
-- delete the first element in vntb1
vntb1.DELETE(1);
-- delete the first string
-- from the second table in the nested table
vntb1(2).DELETE(1);
END;
/
>>>>>>>>>my excercise>>>>>>>>>>>>>>>>>
DECLARE
TYPE tb1 IS TABLE OF VARCHAR2(20);
TYPE Ntb1 IS TABLE OF tb1; -- table of table elements
TYPE Tv1 IS VARRAY(10) OF INTEGER;
TYPE ntb2 IS TABLE OF tv1; -- table of varray elements
vtb1 tb1 := tb1('one', 'three');
vntb1 ntb1 := ntb1(vtb1);
vntb2 ntb2 := ntb2(tv1(3,5), tv1(5,7,3));
-- table of varray elements
BEGIN
vntb1.EXTEND;
vntb1(2) := vntb1(1);
dbms_output.put_line(vntb1(1)(1)||' '||vntb1(2)(2));
-- delete the first element in vntb1
vntb1.DELETE(1);
dbms_output.put_line(vntb1(2)(1)||' '||vntb1(2)(2));
-- delete the first string
-- from the second table in the nested table
vntb1(2).DELETE(1);
END;
/
>>>>>>>>>my excercise>>>>>>>>>>>>>>>>>
DECLARE
TYPE tb1 IS TABLE OF VARCHAR2(20);
TYPE Ntb1 IS TABLE OF tb1; -- table of table elements
TYPE Tv1 IS VARRAY(10) OF INTEGER;
TYPE ntb2 IS TABLE OF tv1; -- table of varray elements
vtb1 tb1 := tb1('one', 'three');
vntb1 ntb1 := ntb1(vtb1);
vntb2 ntb2 := ntb2(tv1(3,5), tv1(5,7,3));
-- table of varray elements
BEGIN
vntb1.EXTEND;
vntb1(2) := vntb1(1);
dbms_output.put_line(vntb1(1)(1)||' '||vntb1(2)(2));
-- delete the first element in vntb1
vntb1.DELETE(1);
dbms_output.put_line(vntb1(2)(1)||' '||vntb1(2)(2));
-- delete the first string
-- from the second table in the nested table
vntb1(2).DELETE(1);
dbms_output.put_line(vntb1(2)(2)||' '||vntb1(2)(2));
END;
/
>>>>>>>>>my excercise>>>>>>>>>>>>>>>>>
create procedure prln(obj varchar2) is
begin
dbms_output.put_line(obj);
end;
/
Example 5-27 : Multilevel Associative Array.
-------------------------------------------
Declare
Type tb1 is table of integer index by pls_integer;
Type ntb1 is table of tb1 index by pls_integer;
Type va1 is varray(10) of varchar2(20);
Type ntb2 is table of va1 index by pls_integer;
v1 va1 := va1('hello', 'world');
v2 ntb1;
v3 ntb2;
v4 tb1;
v5 tb1;
begin
v4(1) := 34;
v4(2) := 46456;
v4(456) := 343;
v2(23) := v4;
v3 (34) := va1(33, 456, 656, 343);
v5(1) := 10;
v5(2) := 20;
v2(35) := v5;
--v2(35)(2) := 78;
V2(35) := V4;
prln(v2(35)(2));
prln(v5.count);
end;
/
Example 5-28 : Checking Wheter a Collection Element Exists.
----------------------------------------------------------------------------
Declare
Type NumList is table of Integer;
n NumList := NumList(1, 3, 5, 7);
begin
--n.delete(2);
prln(n(1));
if n.exists(1) then
prln('OK, Element #1 exists! ');
else
prln('OK, Element #1 has been Deleted!');
end if;
if n.exists(2) = false then
prln('OK, Element #2 has been Deleted!');
else
prln(n(2));
end if;
if n.exists(99) = false then
prln('OK, Element #99 does not exists at all! ');
end if;
end;
/
Example 5-29 : Counting Collection Elements with Count.
-----------------------------------------------------------------------
Declare
Type NumList is table of number;
n NumList := NumList (2, 4, 6, 8);
Begin
dbms_output.put_line('There are '|| n.count || ' elements in N.');
n.extend(3); -- Add 3 new elements at the end.
dbms_output.put_line('There are '|| n.count || ' elements in N.');
n := NumList (86, 99, 15);
dbms_output.put_line('There are '|| n.count || ' elements in N.');
n.trim(2);
dbms_output.put_line('There are '|| n.count || ' elements in N.');
end;
/
Example 5-30 : Checking the Maximum Size of a Collection with LIMIT.
------------------------------------------------------------------------------------------
Declare
Type dnames_var is varray(7) of varchar2(30);
dept_names dnames_var := dnames_var('Shipping', 'Sales', 'Finance', 'Payroll');
Begin
prln('dept_names has '|| dept_names.count);
prln('dept_names''s type can hold a maximum of '|| dept_names.limit ||' elements');
prln('The maximum number you can use with '|| ' dept_names.extend() is '|| (dept_names.limit-dept_names.count));
prln(dept_names.first || ' '|| dept_names.last);
end;
/
Example 5-31: Using First and Last with a Collection.
------------------------------------------------------------------
Declare
Type NumList is table of number;
n NumList := NumList (1, 3, 5, 7);
counter integer;
Begin
prln('The first subscript of N is '||n.first);
prln('The last subscript of N is '||n.last);
for i in n.first..n.last loop
prln('Element #' || i || ' = ' || n(i));
end loop;
n.delete(2);
if n is not null then
counter := n.first;
while counter is not null loop
prln('Element # '|| counter || ' = '|| n(counter));
counter := n.next(counter);
end loop;
else
prln('N is null, nothing to do' );
end if;
end;
/
Example 5-32 : Using Prior and Next to Access Collection Elements.
-------------------------------------------------------------------------------------
Declare
Type NumList is table of number;
n NumList := NumList(1966, 1971, 1984, 1989, 1999);
Begin
prln('The element after #2 is #'||n.next(2));
prln('The element before #2 is #'||n.prior(2));
n.delete(3);
prln('The element after #2 is #'||n.next(2));
if n.prior(n.first) is null then
prln('Can''t get Prior of the first element or Next of the Last');
end if;
end;
/
Example 5-33 : Using Next to Access Elements of a Nested Table.
-----------------------------------------------------------------------------------
Declare
Type NumList is table of number;
n NumList
Example 5–34 Using EXTEND to Increase the Size of a Collection
----------------------------------------------------------------------------------
DECLARE
TYPE NumList IS TABLE OF INTEGER;
n NumList := NumList(2,4,6,8);
x NumList := NumList(1,3);
PROCEDURE print_numlist(the_list NumList) IS
output VARCHAR2(128);
BEGIN
FOR i IN the_list.FIRST .. the_list.LAST
LOOP
output :=
output || NVL(TO_CHAR(the_list(i)),'NULL') || ' ';
END LOOP;
DBMS_OUTPUT.PUT_LINE(output);
END;
BEGIN
DBMS_OUTPUT.PUT_LINE
('At first, N has ' || n.COUNT || ' elements.');
n.EXTEND(5); -- Add 5 elements at the end.
DBMS_OUTPUT.PUT_LINE
('Now N has ' || n.COUNT || ' elements.');
-- Elements 5, 6, 7, 8, and 9 are all NULL.
print_numlist(n);
DBMS_OUTPUT.PUT_LINE
('At first, X has ' || x.COUNT || ' elements.');
x.EXTEND(4,2); -- Add 4 elements at the end.
DBMS_OUTPUT.PUT_LINE
('Now X has ' || x.COUNT || ' elements.');
-- Elements 3, 4, 5, and 6 are copies of element #2.
print_numlist(x);
END;
/
Example : 5-35 : Using Trim to Decrease the Size of a Collection.
--------------------------------------------------------------------------------
Declare
Type NumList is table of number;
n NumList := NumList (1, 2, 3, 5, 7, 11);
procedure print_numlist(the_list NumList) is
output varchar2(128);
begin
if
n.count = 0 then
prln('No elements in collection !');
else
for i in the_list.first..the_list.last
loop
output := output|| nvl(to_char(the_list(i)), 'NULL') || ' ' ;
end loop;
prln(output);
end if;
end;
Begin
print_numlist(n);
n.trim(2);
print_numlist(n);
n.trim(n.count);
print_numlist(n);
Begin
n := NumList (1, 2 , 3);
n.trim(100);
Exception
when subscript_beyond_count then
prln('There are not 100 elemnts to trim');
n := NumList(1, 2, 3, 4);
n.delete(3);
n.trim(2);
print_numList(n);
end;
end;
/
Example 5-36 : Using Trim on Deleted Elements.
-----------------------------------------------------------
Declare
Type CourseList is table of Varchar2(10);
Courses CourseList;
Begin
Courses := CourseList('Biol 4412', 'Psych 3112', 'Anth 3001');
prln( courses.last);
courses.delete(courses.last);
prln(courses.last);
courses.trim(courses.count);
prln(courses(courses.count));
prln(courses(1));
end;
/
Example 5-37 : Using the Delete Method on a Collection.
----------------------------------------------------------------------
Declare
Type NumList is table of number;
n NumList := NumList(10, 20, 30, 40, 50, 60, 70, 80, 90, 100);
Type NickList is table of Varchar2(64) index by varchar2(21);
nickNames NickList;
Begin
n.delete(2);
n.delete(3, 6); -- deletes elements 3 through 6
n.delete(7, 7);
n.delete(6, 3); -- does nothing since 6 > 3
n.delete; -- delete all elements.
nicknames('Bob') := 'Robert';
nicknames('Buffy') := 'Esmerelda';
nicknames('Chip') := 'Charles';
nicknames('Dan') := 'Daniel';
nicknames('Fluffy') := 'Ernestina';
nicknames('Rob') := 'Robert';
nicknames('Dan') := 'Daniel';
prln(nicknames.count);
nicknames.delete('Chip');
prln(nicknames.count);
nicknames.delete;
prln(nicknames.count);
end;
/
Example 5-38 : Collection Exception.
----------------------------------------------
Declare
Type WordList is table of varchar2(5);
Words WordList;
err_msg varchar2(100);
procedure display_error is
Begin
err_msg := substr(sqlerrm, 1, 100);
prln('Error Message = ' || err_msg);
End;
Begin
Begin
words(1) := 10;
Exception
When others then display_error;
end;
words := wordList('1st', '2nd', '3rd');
words(3) := words(1)||'+2';
Begin
words(3) := 'Longer than 5 characters';
exception
when others then display_error;
end;
Begin
words('B') := 'dunno';
exception
when others then display_error;
end;
Begin
words(0) := 'zero';
exception
when others then display_error;
end;
Begin
words(4) := 'maybe';
exception
when others then display_error;
end;
Begin
words.delete(1);
if words(1) = 'First' then NULL;
end if;
exception
when others then display_error;
End;
end;
/
Example 5-39 : How Invalid Subscript are Handled with Delete(n).
----------------------------------------------------------------------------------
Declare
Type NumList is table of number;
nums NumList := NumList(10, 20, 30);
Begin
nums.delete(-1);
nums.delete(3);
nums(3) := 30;
prln(nums.count);
End;
/
Example 5-40 : Incompatibility Between Package and Local Collection Types.
------------------------------------------------------------------------------------------------
Create package pkg as
Type NumList is table of Number;
procedure print_numlist(nums NumList);
end pkg;
/
Create or replace package body pkg as
procedure print_numlist(nums NumList) is
Begin
for i in nums.first..nums.last loop
prln(nums(i));
end loop;
end;
end pkg;
/
Declare
Type NumList is table of number;
n1 pkg.NumList := pkg.NumList(2, 4);
n2 NumList := NumList(6, 8);
Begin
pkg.print_numlist(n1);
--pkg.print_numlist(n2); -- not allowed
end;
/
Example 5-41 : Declaring and Initializing a Simple Record.
-----------------------------------------------------------------------
Declare
Type DeptRecTyp is record(
deptid number (4) not null := 99,
dname departments.department_NAME%type,
loc departments.location_id%type,
region regions%rowtype
);
Dept_Rec DeptRecTyp;
BEGIN
dept_rec.dname := 'PURCHASING';
END;
/
Example 5-42 : Declaring and Initializing RECORD Types.
------------------------------------------------------
DECLARE
Type rec1_t is record (
field1 varchar2(16),
field2 number,
field3 DATE);
Type rec2_t is record (
id integer not null := -1,
name varchar2(64) not null := '[anonymous]'
);
rec1 rec1_t;
rec2 rec2_t;
rec3 employees%rowtype;
Type rec4_t is record (first_name employees.first_name%type,
last_name employees.last_name%type,
rating number
);
rec4 rec4_t;
BEGIN
rec1.field1 := 'Yesterday';
rec1.field2 := 60;
rec1.field3 := trunc(sysdate-1);
prln(rec2.name);
END;
/
Example 5-43 : Using %ROWTYPE to Declare a Record.
-----------------------------------------------------------------------
Declare
Cursor c1 is
select department_id, department_name, location_id
from departments;
rec1 c1%rowtype;
Type DeptRec2 is Record (dept_id departments.department_id%type,
dept_name departments.department_name%type,
dept_loc departments.location_id%type);
rec2 DeptRec2;
Type DeptRec3 is record(
dept_id number,
dept_name varchar2(14),
dept_loc varchar2(13)
);
rec3 DeptRec3;
Begin
null;
end;
/
Example 5-44 : Returning a Record from a Function.
-----------------------------------------------------------------
Declare
Type EmpRecTyp is Record(
emp_id number(6),
salary number(8, 2)
);
Cursor desc_salary return EmpRecTyp is
select employee_id, salary
from employees
order by salary desc;
emp_rec EmpRecTyp;
Function nth_highest_salary(n integer) return EmpRecTyp is
Begin
open desc_salary;
for i in 1..n loop
fetch desc_salary into emp_rec;
end loop;
return emp_rec;
end nth_highest_salary;
Begin
null;
end;
/
>>>>>>>>>>>>>>>>>>>>>>>>>>>
Declare
a number;
b number;
function
mysum(x number, y number) return number is
begin
return x*y;
end mysum;
Begin
prln(mysum(2, 15));
end;
/
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Example 5-45 : Using a Record as Parameter to a Procedure.
---------------------------------------------------------------------------
Declare
Type EmpRecTyp is Record( emp_id number (6), emp_sal number(8, 2));
Procedure raise_salary (emp_info EmpRecTyp) is
Begin
update employees set salary = salary+ salary* .10
where employee_id = emp_info.emp_id;
end raise_salary;
Begin
null;
end;
/
Example 5-46 : Declaring a Nested Record.
-----------------------------------------------------
Declare
Type TimeTyp is record(minutes smallint, hours smallint);
Type meetingTyp is record(day date, time_of Timetyp, dept departments%rowtype, place varchar2(20), purpose varchar2(50));
meeting meetingTyp;
seminar meetingTyp;
Begin
seminar.time_of := meeting.time_of;
end;
/
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Declare
Type TimeTyp is record(minutes smallint, hours smallint);
Type meetingTyp is record(day date, time_of Timetyp, dept departments%rowtype, place varchar2(20), purpose varchar2(50));
meeting meetingTyp;
seminar meetingTyp;
Begin
meeting.day := '01-JUN-15';
seminar.time_of := meeting.time_of;
end;
/
Example 5-47 : Assigning Default values to a record.
----------------------------------------------------------------
declare
type recordType is record(field1 number, field2 varchar2(32) default 'something');
rec1 recordType;
rec2 recordType;
begin
rec1.field1 := 100;
rec1.field2 := 'something else';
rec2.field1 := 200;
rec1 := rec2;
dbms_output.put_line(rec1.field1 ||' ' || rec1.field2);
end;
/
Example 5-48 : Assigning all the fields of a record in one statement.
---------------------------------------------------------------------
declare
type DeptRec1 is record (dept_num number(2), dept_name varchar2(14));
type DeptRec2 is record (dept_num number(2), dept_name varchar2(14));
dept1_info deptRec1;
dept2_info deptRec2;
dept3_info deptRec2;
begin
--dept1_info := dept2_info;
dept3_info.dept_num := 10;
dept3_info.dept_name := 'Admin';
dept2_info := dept3_info;
dbms_output.put_line('Department Id is '|| dept2_info.dept_num);
end;
/
------------------------------------------------------------------------
declare
type recordtype is record (last employees.last_name%type, id employees.employee_id%type);
cursor c1 is select last_name, employee_id from employees;
rec1 recordType;
rec2 c1%rowtype;
begin
select last_name, employee_id into rec2 from employees
where rownum <2;
rec1 := rec2;
dbms_output.put_line(rec1.last);
end;
/
---------------------------------------------------------------------------
declare
cursor c1 is select last_name from employees;
begin
for item in c1 loop
dbms_output.put_line(item.last_name);
end loop;
end;
/
Example : 5-49 Using select itno to assign values in a Record.
----------------------------------------------------------------------------
declare
type recordType is record(last employees.last_name%type, id employees.employee_id%type);
rec1 recordType;
begin
select last_name, employee_id into rec1 from employees where rownum <2;
dbms_output.put_line('employee '|| rec1.id);
end;
/
declare
type recordType is record(last employees.last_name%type, id employees.employee_id%type);
rec1 recordType;
begin
select last_name, employee_id into rec1 from employees where rownum <2;
dbms_output.put_line('employee id : '|| rec1.id);
dbms_output.put_line('employee name : '|| rec1.last);
end;
/
--------------------------
declare
cursor c1 is select employee_id, last_name from employees order by employee_id;
v1 c1%rowtype;
begin
open c1;
fetch c1 into v1;
dbms_output.put_line(v1.employee_id ||' '||v1.last_name );
end;
/
Example 5-50 : Insertig a PL/SQL Record Using %Rowtype
---------------------------------------------------------------------------
declare
dept_info departments%rowtype;
begin
dept_info.department_id := 300;
dept_info.department_name := 'Personnel';
dept_info.location_id := 1700;
insert into departments values dept_info;
end;
/
Example 5-51 : Updating a Row Using a Record
--------------------------------------------------------------------------
declare
dept_info departments%rowtype;
begin
dept_info.department_id := 300;
dept_info.department_name := 'Personnel2';
dept_info.location_id := 1700;
update departments set row = dept_info
where department_id = 300;
end;
/
Example 5-52 : Using the Returning Into Clause with a Record.
---------------------------------------------------------------------------
Declare
type EmpRec is record (last_name employees.last_name%type, salary employees.salary%type, commission_pct employees.commission_pct%type);
emp_info EmpRec;
emp_id number := 100;
begin
update employees set salary = salary* nvl(commission_pct, 1)
where employee_id = emp_id
returning last_name, salary, commission_pct into emp_info;
dbms_output.put_line('Just gave a raise to '|| emp_info.last_name || ' who now makes '|| emp_info.salary);
rollback;
end;
/
---------------------------------------------------------------------------------
Declare
type EmpRec is record (last_name employees.last_name%type, salary employees.salary%type, commission_pct employees.commission_pct%type);
emp_info EmpRec;
emp_id number := 101;
begin
delete from emp
where employee_id = emp_id
returning last_name, salary, commission_pct into emp_info;
dbms_output.put_line('Just gave a raise to '|| emp_info.last_name || ' who now makes '|| emp_info.salary);
rollback;
end;
/
Example 5-53 : Using Bulk Collect with Selectr into statement.
-------------------------------------------------------------
Declare
Type employeeSet is table of employees%rowtype;
underPaid employeeSet;
Cursor c1 is select first_name, last_name from employees;
type NameSet is table of c1%rowtype;
some_names NameSet;
begin
select * bulk collect into underPaid from employees
where salary < 5000 order by salary desc;
dbms_output.put_line(underPaid.count|| ' people make less than 5000');
for i in underPaid.first..underPaid.last loop
dbms_output.put_line(underpaid(i).last_name || ' makes '|| underPaid(i).salary || ' '||underPaid(i).department_id);
end loop;
select first_name, last_name bulk collect into some_names from employees where rownum < 11;
for i in some_names.first..some_names.last loop
dbms_output.put_line(some_names(i).first_name ||' ' || some_names(i).last_name);
end loop;
end;
/
>>>>>>>>>>>>excercise>>>>>>>>>>
declare
a departments%rowtype;
begin
a.department_id := 100;
dbms_output.put_line(a.department_id);
end;
/
Creating Object
--------------------
CREATE OR REPLACE TYPE CUSTOMER_TYP_DEMO AS OBJECT (
CUSTOMER_ID NUMBER(6),
CUST_FIRST_NAME VARCHAR2(2),
CUST_LAST_NAME VARCHAR2(20),
CUST_ADDRESS CUST_ADDRESS_TYP,
PHONE_NUMBERS PHONE_LIST_TYP,
NLS_LANGUAGE VARCHAR2(30),
CREDIT_LIMIT NUMBER(30),
CUST_EMAIL VARCHAR2(30),
CUST_ORDERS ORDER_LIST_TYP
);
/
CREATE OR REPLACE TYPE ASS AS TABLE OF CUSTOMER_TYP_DEMO;
/
CREATE TYPE DATA_TYP1 AS OBJECT (YEAR NUMBER, MEMBER FUNCTION PROD (INVENT NUMBER) RETURN NUMBER);
/
CREATE TYPE BODY DATA_TYP1 IS
MEMBER FUNCTION PROD(INVENT NUMBER) RETURN NUMBER IS
BEGIN
RETURN (YEAR + INVENT);
END;
END;
/
CREATE TYPE CORPORATE_CUSTOMER_TYP_DEMO UNDER CUSTOMER_TYP (ACCOUNT_MGR_ID NUMBER(6));
/
CREATE or replace TYPE address_t AS OBJECT
EXTERNAL NAME 'Examples.Address' LANGUAGE JAVA
USING SQLData(
STREET_ATTR VARCHAR (250) EXTERNAL NAME 'STREET',
CITTY_ATTR VARCHAR(250) EXTERNAL NAME 'CITY',
STATE VARCHAR(50) EXTERNAL NAME 'STATE',
ZIP_CODE_ATTR NUMBER EXTERNAL NAME 'ZIPCODE',
STATIC FUNCTION recom_width RETURN NUMBER
EXTERNAL VARIABLE NAME 'recommendedWidth',
STATIC FUNCTION create_address RETURN address_t
EXTERNAL NAME 'create() return Examples.Address',
STATIC FUNCTION construct RETURN address_t
EXTERNAL NAME 'create() return Examples.Address',
STATIC FUNCTION create_address (street VARCHAR, city VARCHAR, state VARCHAR, zip NUMBER) RETURN address_t
EXTERNAL NAME 'create (java.lang.String, java.lang.String, java.lang.String, int ) return Examples.Address',
STATIC FUNCTION construct (street VARCHAR, city VARCHAR, state VARCHAR, zip NUMBER) RETURN address_t
EXTERNAL NAME 'create (java.lang.String, java.lang.String, java.lang.String, int ) return Examples.Address',
MEMBER FUNCTION to_string RETURN VARCHAR
EXTERNAL NAME 'tojava.lang.String() return java.lang.String',
MEMBER FUNCTION strip RETURN SELF AS RESULT
EXTERNAL NAME 'removeLeadingBlanks() return Examples.Address'
) NOT FINAL;
/
Create type my_type as object
external name 'Examples.Address' language java
using SQLData (myName varchar(25) external name 'myName') not final;
/
Create type my_type2 as object
external name 'Examples' language java
using SQLData (myName varchar(25) external name 'myName') not final;
/
Create type my_type3 as object
external name 'EX' language java
using SQLData (myName varchar(25) external name 'myName') not final;
/
Create or replace Type long_address_t
under address_t
external Name 'Examples.LongAddress' Language Java
Using SQLData(
street2_attr varchar(250) external name 'street2',
country_attr varchar(250) external name 'country',
address_code_attr varchar(50) external name 'addrcode',
static function create_address return long_address_t
external name 'create () return Examples.LongAddress',
static function construct (street varchar, city varchar, state varchar, country varchar, addrs_cd varchar) return long_address_t
external name 'create (java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) return Examples.LongAddress',
static function construct return long_address_t
external name 'Examples.LongAddress() return Examples.LongAddress',
Static function create_longaddress(street varchar, city varchar, state varchar, country varchar, addrs_cd varchar) return long_address_t
external name 'Examples.LongAddress(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String ) return Examples.LongAddress',
member function get_country return varchar
external name 'country_with_code () return java.lang.String'
);
/
Create type person_t as object (name varchar2(100), ssn number) not final;
/
Create type employee_t under person_t (department_id number, salary number) not final;
/
Create type part_time_emp_t under employee_t (num_hrs number);
/
Create type textdoc_typ as object (document_typ varchar2(32), formatted_doc blob);
/
Create type phone_list_typ_demo as varray(5) of varchar2(25);
/
Create type textdoc_tab as table of textdoc_typ;
/
create type cust_address_typ2 as object (
street_address varchar2(40),
postal_code varchar2(10),
city varchar2(30),
state_province varchar2(10),
country_id char(2),
phone phone_list_typ
);
/
create type cust_nt_address_typ as table of cust_address_typ2;
/
CREATE TYPE DEMO_TYP1 AS OBJECT (X NUMBER, Y NUMBER);
/
CREATE TABLE DEMO_TAB1 (B1 NUMBER, B2 DEMO_TYP1);
/
INSERT INTO DEMO_TAB1 VALUES (1, DEMO_TYP1(2, 3));
/
CREATE OR REPLACE TYPE DEMO_TYP2 AS OBJECT (A1 NUMBER, MEMBER FUNCTION GET_SQUARE RETURN NUMBER);
/
CREATE TABLE DEMO_TAB2 (COL DEMO_TYP2);
/
CREATE OR REPLACE TYPE BODY DEMO_TYP2 IS
MEMBER FUNCTION GET_SQUARE
RETURN NUMBER
IS X NUMBER;
BEGIN
SELECT C.COL.A1 * C.COL.A1 INTO X FROM DEMO_TAB2 C;
RETURN (X);
END;
END;
/
ANALYTIC FUNCTION : 1. LAG FUNCTION
LAG FUNCTION
------------------------
Syntax: LAG (VALUE EXPRESSION[, OFFSET, DEFAULT[) [RESPECT/IGNORE NULLS] OVER ([QUERY_PARTITION_CLAUSE] ORDER_BY_CLAUSE).................
⦁ Single Row function একটা মাত্র row কে process করে এবং একটি মাত্র value রিটার্ন করে।
⦁ Multiple Row Function একাধিক row কে process করে এবং একটি মাত্র value রিটার্ন করে।
⦁ Analytic Function একাধিক row কে process করে এবং প্রত্যেক row এর বিপরীতে একটি value রিটার্ন করে।
Lag একটি analytic function. এর দ্বারা self join ছাড়া একই সময়ে একাধিক row কে access করা যায়। এই function টি একাধিক row কে process করে এবং প্রত্যেক row এর against এ value রিটার্ন করে।
OFFSET clause টি optional. এই clause টি ব্যবহার না করলে Default 1 নিয়ে নিবে। offset টি শুন্যের উপরে যে কোন integer ব্যবহার করা যাবে। offset দ্বারা প্রদত্ত row থেকে retrieved row এর দূরত্ব বুঝায়।
যেমন- আমরা employees table এর employee_id, last_name এবং salary দেখব। পাশাপাশি প্রত্যেক employee এর salary এর পাশে প্রত্যেক্ অন্য কোন employee এর salary দেখব যে প্রথম employee এর পূর্বে বা পরে join করেছে। অথবা বর্ণানুক্রিমকভাবে সাজালে যার নাম প্রথম ব্যক্তির আগে বা পরে আসে। যে column এর উপর ভিত্তি করে আগে বা পরে নির্ধারণ হবে তা order_by_clause এ ব্যবহৃত হবে।
DEFAUL clause টি দ্বারা বুঝায় যদি কোন value পাওয়া না যায় তাহলে Default Value প্রদর্শন করবে।
RESPECT/IGNORE NULLS clause টিও optional.
নিচের code টি job_id ‘PU_CLERK’ এর অধীনে থাকা employee এর join date, name এবং salary দেখাবে । পাশাপাশি অন্য column আকারে প্রত্যেক employee এর পাশে অন্য একজন employee এর salary প্রদর্শন করবে যে প্রদত্ত employee এর ১ ডেট পূর্বে যোগদান করেছে।
-----------------------------------------------------------------------------------------------------------------------------------------
SELECT HIRE_DATE, LAST_NAME, SALARY, LAG(SALARY, 1, 0) OVER (ORDER BY HIRE_DATE ) AS PREV_SAL FROM EMPLOYEES
WHERE JOB_ID = 'PU_CLERK'
ORDER BY HIRE_DATE;
এই রেজাল্টে আমরা দেখতে পাচ্ছি,
PU_CLERK এর অধীনে প্রথম জয়ন করা employee এর hire_date 18-MAY-95. তার পূর্বে আর কোন employee জয়ন করেনি। তাই prev_sal তে ০ দেখাচ্ছে । কারন আমরা default clause 0 দিয়েছি। এই job_id এর অধীনে দ্বিতীয় ডেট এ জয়ন করা employee টবিয়াস। তার সেলারি ২৮০০ টাকা। তার পাশের কলামে দেখাচ্ছে ৩১০০ টাকা যা হল এক ডেট আগে জয়ন করা employee খূ এর সেলারি।
-----------------------------------------------------------------------------------------------------------------------------------------
নিচের code টি job_id ‘PU_CLERK’ এর অধীনে থাকা employee এর join date, name এবং salary দেখাবে । পাশাপাশি অন্য column আকারে প্রত্যেক employee এর পাশে অন্য একজন employee এর salary প্রদর্শন করবে যে প্রদত্ত employee এর ১ ডেট পর যোগদান করেছে।
SELECT HIRE_DATE, LAST_NAME, SALARY, LAG(SALARY, 1, 0) OVER (ORDER BY HIRE_DATE DESC) AS PREV_SAL FROM EMPLOYEES
WHERE JOB_ID = 'PU_CLERK'
ORDER BY HIRE_DATE;
------------------------------------------------------------------------------------------------------------------------------------------
নিচর code টি দ্বারা আমরা একটি নির্দিষ্ট job_id (PU_CLERK) এর against এ hire_date, last_name, salary দেখব, পাশাপাশি পাশের কলামে অন্য একজন employee এর last_name দেখব যে এক ডেট আগে জয়ন করেছে এবং আরেকটি কলামে অন্য একজন employee এর salary দেখব যে দুই ডেট আগে জয়ন করেছে।
SELECT HIRE_DATE, LAST_NAME, SALARY,
LAG(LAST_NAME, 1, 0) OVER (ORDER BY HIRE_DATE ) AS PREV_NAME,
LAG(SALARY, 2, 0) OVER (ORDER BY HIRE_DATE ) AS PREV_SAL ,
LAG(DEPARTMENT_ID, 1, 0) OVER (ORDER BY DEPARTMENT_ID, 1, 0) AS PREV_DEPT
FROM EMPLOYEES
WHERE JOB_ID = 'PU_CLERK'
ORDER BY HIRE_DATE;
MORE EXERCISES
1. ORDER BY LAST_NAME
SELECT HIRE_DATE, LAST_NAME, SALARY, LAG(SALARY, 4, 0) OVER (ORDER BY LAST_NAME ) AS PREV_SAL FROM EMPLOYEES
--WHERE JOB_ID = 'PU_CLERK'
ORDER BY LAST_NAME;
2. ORDER BY LAST_NAME desc
SELECT HIRE_DATE, LAST_NAME, SALARY, LAG(SALARY,4, 0) OVER (ORDER BY LAST_NAME DESC ) AS PREV_SAL FROM EMPLOYEES
--WHERE JOB_ID = 'PU_CLERK'
ORDER BY LAST_NAME;
3. ORDER BY DEPARTMENT_ID
SELECT EMPLOYEE_ID, LAST_NAME, SALARY, LAG(SALARY, 2, 0) OVER (ORDER BY department_id) OTHER_SALARY FROM EMPLOYEES
WHERE JOB_ID = 'PU_CLERK';
4. ORDER BY JOB_ID
SELECT EMPLOYEE_ID, LAST_NAME, SALARY, LAG(SALARY, 2, 0) OVER (ORDER BY job_id) OTHER_SALARY FROM EMPLOYEES;
5. PARTITION BY DEPARTMENT_ID ORDER BY JOB_ID
SELECT EMPLOYEE_ID, LAST_NAME, SALARY, LAG(SALARY, 2, 0) OVER (partition by department_id ORDER BY job_id) OTHER_SALARY FROM EMPLOYEES
ORDER BY DEPARTMENT_ID;
SUGGESTIONS ARE WELCOME
PREPARED BY MASUMKHAN/ROUND21
Subscribe to:
Posts (Atom)