Ubd Lab9

You might also like

Download as doc, pdf, or txt
Download as doc, pdf, or txt
You are on page 1of 8

Tema nr.

9
Observație!
Scrieți rezolvarea direct în acest document!

Creating Packages
1. Create the specification for the check_emp_pkg which you studied in this lesson. The
specification should declare a constant and two procedures, as follows:

 g_max_length_of_service, datatype NUMBER, initialized to 100


 chk_hiredate with one input parameter having the same datatype as employees.hire_date
 chk_dept_mgr with two input parameters having the same datatypes as
employees.employee_id and employees.manager_id.

CREATE OR REPLACE PACKAGE check_emp_pkg IS


g_max_length_of_service NUMBER := 100;
PROCEDURE chk_hiredate(p_hire_date employees.hire_date%TYPE);
PROCEDURE chk_dept_mgr(p_employee_id employees.employee_id%TYPE,
p_manager_id
employees.manager_id%TYPE);
END;

2. Create the package body for check_emp_pkg. Remember that the names and parameters of
the procedures in the body must be identical to those in the specification, or the body will not
compile.

The code for chk_hiredate should RAISE_APPLICATION_ERROR if the employee was hired
more than 100 years ago (hint: use MONTHS_BETWEEN, comparing with
g_max_length_of_service * 12).

The second procedure, chk_dept_mgr, accepts two input parameters: an employee_id and a
manager_id. The code should find the manager of the employee’s department and check whether
this manager has the same manager_id as the second parameter. If the manager_id is the same,
display a suitable “success” message; if they are different, raise an application error. Include an
exception handler for NO_DATA_FOUND.

CREATE OR REPLACE PACKAGE BODY check_emp_pkg IS


PROCEDURE chk_hiredate(p_hire_date employees.hire_date%TYPE) IS
BEGIN
DBMS_OUTPUT.PUT_LINE(MONTHS_BETWEEN(SYSDATE, p_hire_date ));
IF (MONTHS_BETWEEN(SYSDATE, p_hire_date ) >
g_max_length_of_service * 12)
THEN
RAISE_APPLICATION_ERROR(-20001, 'Ai iesit la pensie de ceva
timp!');
ELSE DBMS_OUTPUT.PUT_LINE('te asteptam la munca!');
END IF;
END chk_hiredate;
PROCEDURE chk_dept_mgr(p_employee_id employees.employee_id%TYPE,
p_manager_id employees.manager_id%TYPE) IS
v_department_id employees.department_id%TYPE;
v_manager_id departments.manager_id%TYPE;
BEGIN
SELECT department_id
INTO v_department_id
FROM employees
WHERE employee_id=p_employee_id;
SELECT manager_id
INTO v_manager_id
FROM departments
WHERE department_id=v_department_id;
IF (v_manager_id = p_manager_id) THEN
DBMS_OUTPUT.PUT_LINE('OK');
ELSE
RAISE_APPLICATION_ERROR(-20202, 'ID-ul managerului este
incorect');
END IF;
EXCEPTION
WHEN no_data_found THEN
RAISE_APPLICATION_ERROR(-20203, 'Departamentul sau ID-ul
angajatului nu exista');
END chk_dept_mgr;
END check_emp_pkg;

The following sample data from the employees and departments tables may help you:

Departments:

Employees:

Passing parameters (174,149) would be successful, while (174,176) would raise an error.
3. Procedure chk_hiredate:
A. Test the chk_hiredate procedure using input value 17-Jan-87 (it should succeed).

BEGIN
check_emp_pkg.chk_hiredate(TO_DATE('17-01-1987','DD-MM-YYYY'));
END;

B. Test the chk_dept_mgr procedure twice using input values (174,149) and (174,176). The first
should succeed while the second should fail.
BEGIN
check_emp_pkg.chk_dept_mgr(174, 149);
END;

BEGIN
check_emp_pkg.chk_dept_mgr(174, 176);
END;
4. Now you want to modify the package so that the chk_dept_mgr procedure displays a
different error message if the two manager_ids are different. What do you need to recreate:
the Specification, the Body, or both? Make the change and test it again, using (174,176) as
before.
Doar corpul procedurii va fi modificat, mai exact:
RAISE_APPLICATION_ERROR(-20202, ‘ Cel de-al doilea ID nu
corespunde managerului angajatului care detine primul ID ’);

Advanced Package Concepts

1. Create a package called overload. The package should contain three procedures all called
what_am_i. The first procedure should accept a VARCHAR2 as an IN parameter, the second a
NUMBER and the third a DATE. Each procedure should display a simple message to show
which datatype was passed to it. For example, the first procedure could display “Here I am a
Varchar2”. Save your work for later. When you are done, describe the package.

CREATE OR REPLACE PACKAGE overload IS


PROCEDURE what_am_i(p_in VARCHAR2);
PROCEDURE what_am_i(p_in NUMBER);
PROCEDURE what_am_i(p_in DATE);
END;

CREATE OR REPLACE PACKAGE BODY overload IS


PROCEDURE what_am_i(p_in IN VARCHAR2)
IS BEGIN
DBMS_OUTPUT.PUT_LINE('Here I am a VARCHAR2');
END what_am_i;
PROCEDURE what_am_i(p_in IN NUMBER)
IS BEGIN
DBMS_OUTPUT.PUT_LINE('Here I am a NUMBER');
END what_am_i;
PROCEDURE what_am_i(p_in IN DATE)
IS BEGIN
DBMS_OUTPUT.PUT_LINE('Here I am a DATE');
END what_am_i;
END overload;

2. Test the overload package by calling it and passing in a character string, a number and a date
respectively. You should see the different messages returned.

BEGIN
overload.what_am_i(40);
END;

BEGIN
overload.what_am_i('Am fost aici');
END;

BEGIN
overload.what_am_i(TO_DATE('14-DEC-1940'));
END;
3. Now modify the overload package to have a fourth procedure in it, again called what_am_i,
accepting two parameters: p_in NUMBER and p_in2 VARCHAR2. Test the new procedure to
verify that it works.
CREATE OR REPLACE PACKAGE overload
IS
PROCEDURE what_am_i(p_in IN VARCHAR2);
PROCEDURE what_am_i(p_in IN NUMBER);
PROCEDURE what_am_i(p_in IN DATE);
PROCEDURE what_am_i(p_in IN NUMBER,p_in2 IN VARCHAR2);
END overload;

CREATE OR REPLACE PACKAGE BODY overload IS


PROCEDURE what_am_i(p_in IN VARCHAR2)
IS BEGIN
DBMS_OUTPUT.PUT_LINE('Here I am a VARCHAR2');
END what_am_i;
PROCEDURE what_am_i(p_in IN NUMBER)
IS BEGIN
DBMS_OUTPUT.PUT_LINE('Here I am a NUMBER');
END what_am_i;
PROCEDURE what_am_i(p_in IN DATE)
IS BEGIN
DBMS_OUTPUT.PUT_LINE('Here I am a DATE');
END what_am_i;
PROCEDURE what_am_i(p_in IN NUMBER,p_in2 IN VARCHAR2)
IS BEGIN
DBMS_OUTPUT.PUT_LINE('Here I am a NUMBER and a VARCHAR2');
END what_am_i;
END overload;

BEGIN
overload.what_am_i(20,'nope');
END;

4. Modify the overload package specification again to add a fifth procedure called what_am_i with
the same two IN parameters as the fourth procedure. Try to recreate the specification. What
happens and why?

CREATE OR REPLACE PACKAGE overload


IS
PROCEDURE what_am_i(p_in IN VARCHAR2);
PROCEDURE what_am_i(p_in IN NUMBER);
PROCEDURE what_am_i(p_in IN DATE);
PROCEDURE what_am_i(p_in IN NUMBER,p_in2 IN VARCHAR2);
PROCEDURE what_am_i(p_in IN NUMBER,p_in2 IN VARCHAR2);
END overload;

5. Package init_pkg

A. Create a package init_pkg as follows:

CREATE OR REPLACE PACKAGE init_pkg IS


g_max_sal employees.salary%TYPE;
PROCEDURE get_emp_sal
(p_emp_id IN employees.employee_id%TYPE);
END init_pkg;

CREATE OR REPLACE PACKAGE BODY init_pkg IS


PROCEDURE get_emp_sal
(p_emp_id IN employees.employee_id%TYPE) IS
v_salary employees.salary%TYPE;
BEGIN
SELECT salary INTO v_salary
FROM employees
WHERE employee_id = p_emp_id;
IF v_salary > (g_max_sal / 2) THEN
dbms_output.put_line('This employee earns more
than half the maximum salary');
ELSE
dbms_output.put_line('This employee earns less
than half');
END IF;
END get_emp_sal;
BEGIN
SELECT MAX(salary) INTO g_max_sal
FROM employees;
END init_pkg;

B. Now execute the following anonymous block. Explain the output.

BEGIN
init_pkg.get_emp_sal(101);
init_pkg.g_max_sal := 40000;
init_pkg.get_emp_sal(101);
END;
Pachetul init_pkg contine o variabila care va reprezenta salariul
maxim pe ntru toti angajatii, si o functie care returneaza daca
un anumit angajat primeste un salariu mai mare decat jumatate din
salariul maxim. Initial, la crearea pachetului, maximul se
seteaza cu adevratul maxim, iar jangajatul cu id-ul 101 primeste
mai mult decat jumatate din acel maxim. La al doilea apel insa,
maximul a fost modificat artificial, rezultand in modificarea
outputului procedurii, salariul angajatului 101 nefiind mai mare
decat jumatate din noul salariu maxim artificial.

You might also like