You are on page 1of 3

Dpartement Informatique et Statistique, ICOM, Universit Lumire Lyon 2 M1 Informatique Year 2013-2014 Database programming Labwork #4: Subprograms

ms J. Darmont (http://eric.univ-lyon2.fr/~jdarmont/), 15/07/13

1. Write an anonymous PL/SQL block that displays the n first employees in table EMP (you can copy table DARMONT.EMP again if you dropped it). Number n can be stored in a variable. Deal with the case where n is greater than the number of rows in table EMP (then, display all employees). Test! 2. Transform the anonymous block in to a stored procedure named empnames, with variable n becoming an input parameter. Test by successively using the EXECUTE empnames(3) and EXECUTE empnames(45) statements, for instance. 3. Quit SQL Developer, launch it again and execute procedure empnames again. Conclusion? 4. Write an anonymous PL/SQL block that includes the declaration and initialization of two integer variables n1 and n2, and calls procedure empnames with n1 and n2 in parameters, successively. Test! Exercise #3: Stored function

Exercise #1: Functions and procedures 1. In an anonymous PL/SQL block, define a function named MyMax that inputs two real parameters n1 and n2 and returns a real that equals to the greatest number among n1 and n2. 2. In the main program, declare two real variables a and b and initialize them with any value. Call function MyMax for a and b and display the result. Test! 3. In the same PL/SQL block, define a type TABLE of reals named TabR, and a variable tab of this type. Initialize tab with several values. 4. Define a new function named MultiMax that inputs a TabR collection and returns the greatest number in the collection. Use function MyMax in function MultiMax. In the main program, call function MultiMax for tab and display the result. Test! 5. Complement function MultiMax with an exception that is raised when the input collection is empty (fatal error). Test by initializing tab to empty. 6. Still in the same PL/SQL block, define a procedure named PSort that sorts by ascending order the contents of a TabR collection passed in parameter. Implement a simple permutation sort. 7. Write another procedure named Display that displays (astonishing, isnt it?) all elements of a TabR collection passed in parameter. 8. In the main program, call procedures PSort and Display for tab. What must the parameter mode be in each case? Test! 9. Still in the same PL/SQL block, define a procedure named PSortNoMod that inputs an unsorted TabR collection and outputs a sorted TabR collection. The input TabR collection must retain its initial order of elements (i.e., it must not be modified in output). Call procedure PSortNoMod in the main program. 10. In the main program, declare a second variable tabsort of type TabR and initialize it as empty. Comment calls to procedures PSort and Display from questions #6 and #7 and call procedure PSortNoMod for tab and tabsort. Then, call procedure Display for tab and then tabsort. Test! Exercise #2: Stored procedure Memo: Debugging stored procedures If a stored procedure (or a package or package body) definition is incorrect, Oracle only indicates that it has been created "with compilation errors". To visualize these errores, use the following statement.
SHOW ERRORS Database programming Labwork #4 1/2

1. Transform function MyMax into a stored function (cut and paste the code). 2. Write an anonymous PL/SQL block that includes the declaration and initialization of two real variables n1 and n2, and displays the result of function procedure MyMax(n1, n2). Test! 3. Is it possible to call MyMax directly through an EXECUTE statement out of a PL/SQL block? Find a way to do so.

Database programming Labwork #4

2/2

Solution
-- Ex. #1 DECLARE -- Main program declarations a REAL := 4.5; b REAL := 3.14; TYPE TabR IS TABLE OF REAL; tab TabR := TabR(-3.25, 6.5, 10.2, 9.55, 15.2, 0.255); tabsort TabR := TabR(); -- Function: max of two numbers FUNCTION MyMax(r1 IN REAL, r2 IN REAL) RETURN REAL IS BEGIN IF r1 > r2 THEN RETURN r1; ELSE RETURN r2; END IF; END; -- Function: max in a table FUNCTION MultiMax(t IN TabR) RETURN REAL IS -- Local declarations i INTEGER; m REAL; empty EXCEPTION; BEGIN IF t.COUNT = 0 THEN RAISE empty; END IF; m := t(1); FOR i IN 2..t.COUNT LOOP m := MyMax(m, t(i)); END LOOP; RETURN m; EXCEPTION WHEN empty THEN RAISE_APPLICATION_ERROR(-20599, 'MultiMax error: empty table'); END;

-- Procedure: table sort PROCEDURE PSort(t IN OUT TabR) IS -- Local declarations i INTEGER; j INTEGER; temp REAL; BEGIN FOR i IN 1..t.COUNT-1 LOOP FOR j IN i+1..t.COUNT LOOP IF t(j) < t(i) THEN temp := t(i); t(i) := t(j); t(j) := temp; END IF; END LOOP; END LOOP; END; -- Procedure: table sort without loosing the initial order PROCEDURE PSortNoMod(t_in IN TabR, t_out OUT TabR) IS BEGIN t_out := t_in; PSort(t_out); END; -- Procedure: display a table's content PROCEDURE Display(t IN TabR, label VARCHAR) IS -- Local declarations i INTEGER; output VARCHAR(255) := ''; BEGIN FOR i IN 1..t.COUNT LOOP output := output || ' ' || t(i); END LOOP; DBMS_OUTPUT.PUT_LINE(label || ' =' || output); END; -- Main program BEGIN DBMS_OUTPUT.PUT_LINE('MyMax(' || a || ' ; ' || b || ') = ' || MyMax(a, b)); DBMS_OUTPUT.PUT_LINE('MultiMax = ' || MultiMax(tab)); --PSort(tab); Display(tab, 'Sorted table'); PSortNoMod(tab, tabsort); Display(tab, 'Unsorted table'); Display(tabsort, 'Sorted table'); END;

Database programming Labwork #4

3/2

Database programming Labwork #4

4/2

-- Ex. #2 CREATE OR REPLACE PROCEDURE empnames(n INTEGER) IS CURSOR employees IS SELECT ename FROM emp; e employees%ROWTYPE; BEGIN OPEN employees; FETCH employees INTO e; WHILE employees%FOUND AND employees%ROWCOUNT <= n LOOP DBMS_OUTPUT.PUT_LINE(e.ename); FETCH employees INTO e; END LOOP; CLOSE employees; END; -- Test anonymous block DECLARE n1 INTEGER := 3; n2 INTEGER := 70; BEGIN empnames(n1); empnames(n2); END; -- Ex. #3 CREATE OR REPLACE FUNCTION MyMax(r1 IN REAL, r2 IN REAL) RETURN REAL IS BEGIN IF r1 > r2 THEN RETURN r1; ELSE RETURN r2; END IF; END; -- Test anonymous block DECLARE n1 REAL := 3.1416; n2 REAL := 22; BEGIN DBMS_OUTPUT.PUT_LINE(MyMax(n1, n2)); END; -- The trick EXECUTE DBMS_OUTPUT.PUT_LINE(MyMax(802.25, 501.3))

Database programming Labwork #4

5/2