Вы находитесь на странице: 1из 10

Lab Assignment 9

CIS 208A PL/SQL Programming and SQL

Section 9-1, Exercise #2, 3

2. Create a function called full_name. Pass two parameters to the function: an


employee’s last name and first name. The function should return the full name in
the format: last name, comma and space, first name (for example: Smith, Joe).
Save your code.

A. Test your function from an anonymous block which uses a local variable to store
and display the returned value.

B. Modify your anonymous block from the previous step to remove the local
variable declaration and call the function directly from within the
DBMS_OUTPUT.PUT_LINE call. Test the block again.

C. Now call the function from within a SELECT statement, not a PL/SQL block. Your
SELECT statement should display the first_name, last_name, and full name (using
the function) of all employees in department 50. Your output should look like this.

FIRST_NAME LAST_NAME Full Name


Kevin Mourgos Mourgos, Kevin
Trenna Rajs Rajs, Trenna
Curtis Davies Davies, Curtis
Randall Matos Matos, Randall
Peter Vargas Vargas, Peter
George Bell Bell, George
Tiffany Heiden Heiden, Tiffany

Lab_9_Sp18_208A.doc
3.. Create a function called divide that accepts two numbers as input and returns the
result of dividing the first number by the second number, rounded to two decimal
places. Save your code.

A. Test your function twice from an anonymous block using input values (50,2)
and (25,3).

B. Test your function a third time using input values (16,0). What happens?

C. Modify the function code to trap the ZERO_DIVIDE exception. The exception
handler should return a value of zero from the function if ZERO_DIVIDE is
raised.

D. Test your function again using input values (16,0) as before. Now what happens?

Section 9-2, Exercise #1, 2, 3, 4

The questions in this Practice use partial copies of the employees and departments tables.
Create these copies by executing the following SQL statements:

CREATE TABLE f_emps


AS SELECT employee_id, last_name, salary, department_id
FROM employees;

CREATE TABLE f_depts


AS SELECT department_id, department_name
FROM departments;

Lab_9_Sp18_208A.doc
1. Create and execute a function sal_increase using the following two code samples.
The first creates a function that returns an employee’s new salary if a percentage
increase is granted. The second calls this function in a SELECT statement, using an
increase of 5 percent.

CREATE OR REPLACE FUNCTION sal_increase


(p_salary f_emps.salary%TYPE,
p_percent_incr NUMBER)
RETURN NUMBER
IS
BEGIN
RETURN (p_salary + (p_salary * p_percent_incr / 100));
END;

SELECT last_name, salary, sal_increase(salary , 5)


FROM f_emps;

Now, suppose you want to see the same information in your SELECT statement, but
only for those employees for whom the increased salary would be greater than
10000. Write and test two SELECT statements to do this. In the first, do NOT use
your function. In the second, use your function. Use an increase of 5 percent. Which
do you think is better, and why?

2. Name five places within a SQL statement where a function can be used. The first one
has been done for you (think of four more).

 The column-list of a SELECT statement

3. Modify your anonymous block from question 1 (the block with the calls to the
sal_increase function) to ORDER the results by the increased salary in descending order
(i.e., highest increased salary first)

Lab_9_Sp18_208A.doc
4. Examine the following SELECT statement that lists the total salaries in each
department, for those departments whose total salary is greater than 20000.

SELECT department_id, sum(salary)


FROM f_emps
GROUP BY department_id
HAVING sum(salary) > 20000;

Modify the statement so that it also lists the total salary in each department if a
5 percent increase is granted, and lists those departments whose increased
total salary would be greater than 20000. Your modified statement should call
the sal_increase function twice, once in the column_list and once in the
HAVING clause. Test the modified statement.

Section 9-3, Exercise #1, 3

1. Which of the following statements are true:

A) The Data Dictionary is a list of hard coded table names in all Oracle databases.
B) The Data Dictionary can be updated by all users with SELECT statements.
C) All users of an Oracle Database can see details of all tables in that database.
D) The Data Dictionary is owned by the user called SYS.

3. Write and execute a SELECT statement that lists all the stored objects you have
created in your account so far. The query should return the object name and type and its
status. Order the output by type of object.

Lab_9_Sp18_208A.doc
Section 9-4, Exercise #1 A-E, 2, 3, 4

1. This question shows how exceptions are propagated.

A. Execute the following two SQL statements to create a duplicate of the


departments table, with department_id as the primary key.

CREATE TABLE my_depts AS SELECT * FROM departments;

ALTER TABLE my_depts


ADD CONSTRAINT my_dept_id_pk PRIMARY KEY (department_id);

B. Examine the following code. Create the procedure. Save your work (you will
need to modify the procedure code later).

CREATE OR REPLACE PROCEDURE add_my_dept


(p_dept_id IN VARCHAR2, p_dept_name IN VARCHAR2) IS
BEGIN
INSERT INTO my_depts (department_id,department_name)
VALUES (p_dept_id, p_dept_name);
END add_my_dept;

C. What do you think would happen if you execute this procedure to insert
department_id 10 (which already exists)? Write and execute an anonymous block
to test your theory.

D. Modify your procedure to handle the exception in a generic WHEN OTHERS


exception handler.

E. Now what do you think would happen if you execute this procedure for
department_id 10 (which already exists)? Test it again as in step c.

Lab_9_Sp18_208A.doc
F. Modify the procedure code to leave out the exception section again. Run the code.

CREATE OR REPLACE PROCEDURE add_my_dept (p_dept_id IN VARCHAR2,


p_dept_name IN VARCHAR2) IS BEGIN INSERT INTO my_depts
(department_id,department_name) VALUES (p_dept_id, p_dept_name); END
add_my_dept;

G. Execute the following code to create a new procedure called outer_proc which calls
add_my_dept, passing department_id 10 to it:

CREATE OR REPLACE PROCEDURE outer_proc IS


v_dept NUMBER(2) := 10;
v_dname VARCHAR2(30) := 'Admin';
BEGIN
add_my_dept(v_dept, v_dname);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Exception was propagated to outer_proc');
END;

H. Execute outer_proc from an anonymous block. What happens and why?

2. Write and execute a SELECT statement to list the names of all the procedures you
have created so far.

3. Delete the last procedure you created: outer_proc.

4. Write and execute a SELECT statement to list the source code of your add_my_dept
procedure. Make sure your SELECT statement list the lines of code in the correct order.

Lab_9_Sp18_208A.doc
Section 9-5, Exercise #1, 2

1. If you wanted user SUSAN to be able to execute SELECT and all DML statements on
your countries table, what SQL statement would you execute to give her the required
privileges?

2. User TOM creates a table called TOMTAB, and does not grant you any privileges on
it.

A. If you try to execute the following statement, will it work?

INSERT INTO tom.tomtab (….) VALUES (…..);

B. Examine the following code. Now the INSERT statement has been included in a
procedure which you have created. Will it work now?

CREATE OR REPLACE PROCEDURE my_ins_proc


IS
BEGIN
INSERT into tom.tomtab (….)
VALUES (……);
END;

C. TOM now executes the following statement:

GRANT INSERT ON tomtab TO <your user name>;

Will your my_ins_proc procedure work now? Why or why not?

Lab_9_Sp18_208A.doc
D. TOM now REVOKEs your INSERT privilege on tomtab. TOM then writes the
following procedure. Which privilege must TOM grant to you to allow you to
execute his tom_ins_proc procedure? With this privilege, will the INSERT work
when you invoke TOM’s procedure?

CREATE OR REPLACE PROCEDURE tom_ins_proc


IS
BEGIN
INSERT into tom.tomtab (….)
VALUES (……);
END;

Section 9-6, Exercise #1, 2, 3, 4

The following questions illustrate how definer’s and Invoker’s rights work.

1. Assume the following two procedures have been created in an account called
IACAD_SCHEMA, which also contains an EMPS table:

CREATE OR REPLACE PROCEDURE show_emps_def (p_emp_id IN NUMBER)


IS
v_name emps.name%TYPE;
v_dept_id emps.department_id%TYPE;
v_dept_name emps.department_name%TYPE;
v_sal emps.salary%TYPE;
BEGIN
SELECT name, department_id, department_name, salary
INTO v_name, v_dept_id, v_dept_name, v_sal
FROM emps
WHERE employee_id = p_emp_id;
DBMS_OUTPUT.PUT_LINE('The employee details are: '|| v_name
||' '|| v_dept_id
||' '|| v_dept_name
||' '|| v_sal);
EXCEPTION
WHEN no_data_found THEN
DBMS_OUTPUT.PUT_LINE('No data found for employee id : '
|| p_emp_id
|| '. Sorry, please enter another number and try again.');
END;

Lab_9_Sp18_208A.doc
CREATE OR REPLACE PROCEDURE show_emps_inv (p_emp_id IN NUMBER)
AUTHID CURRENT_USER
IS
v_name emps.name%TYPE;
v_dept_id emps.department_id%TYPE;
v_dept_name emps.department_name%TYPE;
v_sal emps.salary%TYPE;
BEGIN
SELECT name, department_id, department_name, salary
INTO v_name, v_dept_id, v_dept_name, v_sal
FROM emps
WHERE employee_id = p_emp_id;
DBMS_OUTPUT.PUT_LINE('The employee details are: '|| v_name
||' '|| v_dept_id
||' '|| v_dept_name
||' '|| v_sal);
EXCEPTION
WHEN no_data_found THEN
DBMS_OUTPUT.PUT_LINE('No data found for employee id : '
|| p_emp_id||
'. Sorry, please enter another number and try again.');
END;

A. DESCRIBE both procedures, to verify that you can see them in your account.
Remember to prefix the procedure name with the schema name.

B.
Execute a SQL statement to try to select directly from the table used in the
procedures.

C. What are the differences between the two procedures?

2. Execute the first procedure (show_emps_def) with the following actual parameter
value: employee_id = 100. What happens and why?

3.. Execute the first procedure again, this time with employee_id = 10. What happens and
why?

Lab_9_Sp18_208A.doc
4. Execute the second procedure (show_emps_inv) with employee_id = 100. What happens and
why?

Lab_9_Sp18_208A.doc