To select all functions, procedures, packages
SELECT * FROM ALL_OBJECTS WHERE OBJECT_TYPE IN ('FUNCTION','PROCEDURE','PACKAGE')
To select all functions, procedures, packages
SELECT * FROM ALL_OBJECTS WHERE OBJECT_TYPE IN ('FUNCTION','PROCEDURE','PACKAGE')
DECLARE
Declaration section
BEGIN
Exception section
EXCEPTION
WHEN ex_name1 THEN
-Error handling statements
WHEN ex_name2 THEN
-Error handling statements
WHEN Others THEN
-Error handling statements
END;
DELCARE
Declaration section
BEGIN
DECLARE
Declaration section
BEGIN
Execution section
EXCEPTION
Exception section
END;
EXCEPTION
Exception section
END;
Exception Name | Reason | Error Number |
CURSOR_ALREADY_OPEN
|
When you open a cursor that is already open.
|
ORA-06511
|
INVALID_CURSOR
|
When you perform an invalid operation on a cursor like closing a cursor, fetch data from a cursor that is not opened.
|
ORA-01001
|
NO_DATA_FOUND
|
When a SELECT...INTO clause does not return any row from a table.
|
ORA-01403
|
TOO_MANY_ROWS
|
When you SELECT or fetch more than one row into a record or variable.
|
ORA-01422
|
ZERO_DIVIDE
|
When you attempt to divide a number by zero.
|
ORA-01476
|
BEGIN
Execution section
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line ('A SELECT...INTO did not return any row.');
END;
DECLARE
exception_name EXCEPTION;
PRAGMA
EXCEPTION_INIT (exception_name, Err_code);
BEGIN
Execution section
EXCEPTION
WHEN exception_name THEN
handle the exception
END;
DECLARE
Child_rec_exception EXCEPTION;
PRAGMA
EXCEPTION_INIT (Child_rec_exception, -2292);
BEGIN
Delete FROM product where product_id= 104;
EXCEPTION
WHEN Child_rec_exception
THEN Dbms_output.put_line('Child records are present for this product_id.');
END;
/
DECLARE
huge_quantity EXCEPTION;
CURSOR product_quantity is
SELECT p.product_name as name, sum(o.total_units) as units
FROM order_tems o, product p
WHERE o.product_id = p.product_id;
quantity order_tems.total_units%type;
up_limit CONSTANT order_tems.total_units%type := 20;
message VARCHAR2(50);
BEGIN
FOR product_rec in product_quantity LOOP
quantity := product_rec.units;
IF quantity > up_limit THEN
message := 'The number of units of product ' || product_rec.name ||
' is more than 20. Special discounts should be provided.
Rest of the records are skipped. '
RAISE huge_quantity;
ELSIF quantity < up_limit THEN
v_message:= 'The number of unit is below the discount limit.';
END IF;
dbms_output.put_line (message);
END LOOP;
EXCEPTION
WHEN huge_quantity THEN
dbms_output.put_line (message);
END;
/
RAISE_APPLICATION_ERROR (error_number, error_message);
DECLARE
huge_quantity EXCEPTION;
CURSOR product_quantity is
SELECT p.product_name as name, sum(o.total_units) as units
FROM order_tems o, product p
WHERE o.product_id = p.product_id;
quantity order_tems.total_units%type;
up_limit CONSTANT order_tems.total_units%type := 20;
message VARCHAR2(50);
BEGIN
FOR product_rec in product_quantity LOOP
quantity := product_rec.units;
IF quantity > up_limit THEN
RAISE huge_quantity;
ELSIF quantity < up_limit THEN
v_message:= 'The number of unit is below the discount limit.';
END IF;
Dbms_output.put_line (message);
END LOOP;
EXCEPTION
WHEN huge_quantity THEN
raise_application_error(-2100, 'The number of unit is above the discount limit.');
END;
/
CREATE OR REPLACE TYPE rectangle AS OBJECT (length number, width number, member function enlarge( inc number) return rectangle, NOT FINAL member procedure display) NOT FINAL /
CREATE OR REPLACE TYPE BODY rectangle AS MEMBER FUNCTION enlarge(inc number) return rectangle IS BEGIN return rectangle(self.length + inc, self.width + inc); END enlarge; MEMBER PROCEDURE display IS BEGIN dbms_output.put_line('Length: '|| length); dbms_output.put_line('Width: '|| width); END display; END; /
CREATE OR REPLACE TYPE tabletop UNDER rectangle ( material varchar2(20); OVERRIDING member procedure display ) /
CREATE OR REPLACE TYPE BODY tabletop AS OVERRIDING MEMBER PROCEDURE display IS BEGIN dbms_output.put_line('Length: '|| length); dbms_output.put_line('Width: '|| width); dbms_output.put_line('Material: '|| material); END display; /
DECLARE t1 tabletop; t2 tabletop; BEGIN t1:= tabletop(20, 10, 'Wood'); t2 := tabletop(50, 30, 'Steel'); t1.display; t2.display; END; /When the above code is executed at SQL prompt, it produces the following result:
Length: 20 Width: 10 Material: Wood Length: 50 Width: 30 Material: Steel PL/SQL procedure successfully completed.
DECLARE r1 rectangle; r2 rectangle; r3 rectangle; inc_factor number := 5; BEGIN r1 := rectangle(3, 4); r2 := rectangle(5, 7); r3 := r1.enlarge(inc_factor); r3.display; IF (r1 > r2) THEN -- calling measure function r1.display; ELSE r2.display; END IF; END; /
residence := address('103A', 'M.G.Road', 'Jaipur', 'Rajasthan','201301'
CREATE OR REPLACE TYPE address AS OBJECT (house_no varchar2(10), street varchar2(30), city varchar2(20), state varchar2(10), pincode varchar2(10) ); /
dear readers here is sample of using the function REGEXP
select email from <table-name>
where REGEXP_LIKE (EMAIL,'^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$')
/
Yasser
S.N. | Method Name & Purpose |
---|---|
1 | EXISTS(n) Returns TRUE if the nth element in a collection exists; otherwise returns FALSE. |
2 | COUNT Returns the number of elements that a collection currently contains. |
3 | LIMIT Checks the Maximum Size of a Collection. |
4 | FIRST Returns the first (smallest) index numbers in a collection that uses integer subscripts. |
5 | LAST Returns the last (largest) index numbers in a collection that uses integer subscripts. |
6 | PRIOR(n) Returns the index number that precedes index n in a collection. |
7 | NEXT(n) Returns the index number that succeeds index n. |
8 | EXTEND Appends one null element to a collection. |
9 | EXTEND(n) Appends n null elements to a collection. |
10 | EXTEND(n,i) Appends n copies of the ith element to a collection. |
11 | TRIM Removes one element from the end of a collection. |
12 | TRIM(n) Removes n elements from the end of a collection. |
13 | DELETE Removes all elements from a collection, setting COUNT to 0. |
14 | DELETE(n) Removes the nth element from an associative array with a numeric key or a nested table. If the associative array has a string key, the element corresponding to the key value is deleted. If n is null, DELETE(n) does nothing. |
15 | DELETE(m,n) Removes all elements in the range m..n from an associative array or nested table. If m is larger than n or if m or n is null, DELETE(m,n) does nothing. |
Collection Exception | Raised in Situations |
---|---|
COLLECTION_IS_NULL | You try to operate on an atomically null collection. |
NO_DATA_FOUND | A subscript designates an element that was deleted, or a nonexistent element of an associative array. |
SUBSCRIPT_BEYOND_COUNT | A subscript exceeds the number of elements in a collection. |
SUBSCRIPT_OUTSIDE_LIMIT | A subscript is outside the allowed range. |
VALUE_ERROR | A subscript is null or not convertible to the key type. This exception might occur if the key is defined as a PLS_INTEGER range, and the subscript is outside this range. |
FORALL
construct to bulk bind the inserts is reduced to reduce executed timeDECLARE TYPE id_type IS TABLE OF test1.id%TYPE; TYPE description_type IS TABLE OF test1.description%TYPE; t_id id_type := id_type(); t_description description_type := description_type(); BEGIN FOR i IN 1 .. 10000 LOOP t_id.extend; t_description.extend; t_id(t_id.last) := i; t_description(t_description.last) := 'Description: ' || To_Char(i); END LOOP; FORALL i IN t_id.first .. t_id.last INSERT INTO test1 (id, description) VALUES (t_id(i), t_description(i)); FORALL i IN t_id.first .. t_id.last UPDATE test1 SET description = t_description(i) WHERE id = t_id(i); FORALL i IN t_id.first .. t_id.last DELETE test1 WHERE id = t_id(i); COMMIT; END; / PL/SQL procedure successfully completed. Elapsed: 00:00:18.05
------
Using the BULK COLLECT INTO construct reduces this time to approximately 0.01 seconds. DECLARE TYPE id_type IS TABLE OF test1.id%TYPE; TYPE description_type IS TABLE OF test1.description%TYPE; t_id id_type; t_description description_type; BEGIN SELECT id, description BULK COLLECT INTO t_id, t_description FROM test1; END; / PL/SQL procedure successfully completed. Elapsed: 00:00:00.01
DECLARE TYPE t_row IS RECORD ( id NUMBER, description VARCHAR2(50) ); TYPE t_tab IS TABLE OF t_row; l_tab t_tab := t_tab(); BEGIN FOR i IN 1 .. 10 LOOP l_tab.extend(); l_tab(l_tab.last).id := i; l_tab(l_tab.last).description := 'Description for ' || i; :result := :result||' '||l_tab(l_tab.last).id||' - '||l_tab(l_tab.last).description||chr(10); END LOOP; END;
The MEMBER condition allows you to test if an element is member of a collection.
DECLARE TYPE t_tab IS TABLE OF NUMBER; l_tab1 t_tab := t_tab(1,2,3,4,5); BEGIN DBMS_OUTPUT.put('Is 3 MEMBER OF l_tab1? '); IF 3 MEMBER OF l_tab1 THEN DBMS_OUTPUT.put_line('TRUE'); ELSE DBMS_OUTPUT.put_line('FALSE'); END IF; END;
MULTISET INTERSECT
returns the elements that are present in both sets. / 6 7 8 9 10 PL/SQL procedure successfully completed.
MULTISET
conditions against collections, including the following.MULTISET UNION
joins the two collections together, doing the equivalent of a UNION ALL
between the two sets.EXISTS(n)
- Returns TRUE
if the specified element exists.COUNT
- Returns the number of elements in the collection.LIMIT
- Returns the maximum number of elements for a VARRAY, or NULL for nested tables.FIRST
- Returns the index of the first element in the collection.LAST
- Returns the index of the last element in the collection.PRIOR(n)
- Returns the index of the element prior to the specified element.NEXT(n)
- Returns the index of the next element after the specified element.EXTEND
- Appends a single null element to the collection.EXTEND(n)
- Appends n null elements to the collection.EXTEND(n1,n2)
- Appends n1 copies of the n2th element to the collection.TRIM
- Removes a single element from the end of the collection.TRIM(n)
- Removes n elements from the end of the collection.DELETE
- Removes all elements from the collection.DELETE(n)
- Removes element n from the collection.DELETE(n1,n2)
- Removes all elements from n1 to n2 from the collection.DECLARE TYPE table_type_1 IS TABLE OF NUMBER(10); TYPE table_type_2 IS TABLE OF NUMBER(10); v_tab_1 table_type_1; v_tab_2 table_type_2; BEGIN -- Initialise the collection with two values. v_tab_1 := table_type_1(1, 2); -- Assignment causes compilation error. v_tab_2 := v_tab_1; END; / v_tab_2 := v_tab_1; * ERROR at line 11: ORA-06550: line 11, column 14: PLS-00382: expression is of wrong type ORA-06550: line 11, column 3: PL/SQL: Statement ignored SQL>
VARRAY
is similar to a nested table except you must specifiy an upper bound in the declaration. Like nested tables they
can be stored in the database, but unlike nested tables individual elements cannot be deleted so they remain dense.SET SERVEROUTPUT ON SIZE 1000000 DECLARE TYPE table_type IS VARRAY(5) OF NUMBER(10); v_tab table_type; v_idx NUMBER; BEGIN -- Initialise the collection with two values. v_tab := table_type(1, 2); -- Extend the collection with extra values. << load_loop >> FOR i IN 3 .. 5 LOOP v_tab.extend; v_tab(v_tab.last) := i; END LOOP load_loop; -- Can't delete from a VARRAY. -- v_tab.DELETE(3); -- Traverse collection v_idx := v_tab.FIRST; << display_loop >> WHILE v_idx IS NOT NULL LOOP DBMS_OUTPUT.PUT_LINE('The number ' || v_tab(v_idx)); v_idx := v_tab.NEXT(v_idx); END LOOP display_loop; END; / The number 1 The number 2 The number 3 The number 4 The number 5 PL/SQL procedure successfully completed.
DELETE
method to make the collection sparse.
The NEXT
method overcomes the problems of traversing sparse collections.SET SERVEROUTPUT ON SIZE 1000000 DECLARE TYPE table_type IS TABLE OF NUMBER(10); v_tab table_type; v_idx NUMBER; BEGIN -- Initialise the collection with two values. v_tab := table_type(1, 2); -- Extend the collection with extra values. << load_loop >> FOR i IN 3 .. 5 LOOP v_tab.extend; v_tab(v_tab.last) := i; END LOOP load_loop; -- Delete the third item of the collection. v_tab.DELETE(3); -- Traverse sparse collection v_idx := v_tab.FIRST; << display_loop >> WHILE v_idx IS NOT NULL LOOP DBMS_OUTPUT.PUT_LINE('The number ' || v_tab(v_idx)); v_idx := v_tab.NEXT(v_idx); END LOOP display_loop; END; / The number 1 The number 2 The number 4 The number 5 PL/SQL procedure successfully completed.
Index-By Tables (Associative Arrays)
The first type of collection is known as index-by tables. These behave in the same way as arrays except that have no upper bounds, allowing them to constantly extend. As the name implies, the collection is indexed usingBINARY_INTEGER
values, which do not need to be consecutive. The collection is extended by assigning values to an element using an index value that does not currently exist.
SET SERVEROUTPUT ON SIZE 1000000 DECLARE TYPE table_type IS TABLE OF NUMBER(10) INDEX BY BINARY_INTEGER; v_tab table_type; v_idx NUMBER; BEGIN -- Initialise the collection. << load_loop >> FOR i IN 1 .. 5 LOOP v_tab(i) := i; END LOOP load_loop; -- Delete the third item of the collection. v_tab.DELETE(3); -- Traverse sparse collection v_idx := v_tab.FIRST; << display_loop >> WHILE v_idx IS NOT NULL LOOP DBMS_OUTPUT.PUT_LINE('The number ' || v_tab(v_idx)); v_idx := v_tab.NEXT(v_idx); END LOOP display_loop; END; / The number 1 The number 2 The number 4 The number 5 PL/SQL procedure successfully completed.
CREATE OR REPLACE TYPE varray_type_name IS VARRAY(n) of <element_type>Where,
CREATE Or REPLACE TYPE namearray AS VARRAY(3) OF VARCHAR2(10); / Type created.The basic syntax for creating a VRRAY type within a PL/SQL block is:
TYPE varray_type_name IS VARRAY(n) of <element_type>For example:
TYPE namearray IS VARRAY(5) OF VARCHAR2(10); Type grades IS VARRAY(5) OF INTEGER;
DECLARE type namesarray IS VARRAY(5) OF VARCHAR2(10); type grades IS VARRAY(5) OF INTEGER; names namesarray; marks grades; total integer; BEGIN names := namesarray('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; /When the above code is executed at SQL prompt, it produces the following result:
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.
Please note:
- In oracle environment, the starting index for varrays is always 1.
- You can initialize the varray
elements using the constructor method of the varray type, which has the
same name as the varray.
- Varrays are one-dimensional arrays.
- A varray is automatically NULL
when it is declared and must be initialized before its elements can be
referenced.
Example 2
Elements of a varray could also be a %ROWTYPE of any
database table or %TYPE of any database table field. The following example
illustrates the concept:
We will use the CUSTOMERS table stored in our database as:
Select * from
customers;
DECLARE
CURSOR c_customers is
SELECT name FROM customers;
type c_list is varray (6) 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;
/
When the above code is executed at SQL prompt, it produces
the following result:
Customer(1): Ramesh
Customer(2): Khilan
Customer(3):
kaushik
Customer(4): Chaitali
Customer(5): Hardik
Customer(6): Komal
PL/SQL procedure
successfully completed.