Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Практика. Часть 1.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
238.08 Кб
Скачать

Лабораторная работа № 8.

1. Основная задача этого упражнения – продемонстрировать использование

предопределенных исключений. Напишите PL\SQL блок для выборки сотрудников

с определенной зарплатой.

a. Удалите все записи из таблицы messages. С помощью директивы DEFINE

определите переменную sal и инициализируйте ее значением 6000.

b. В секции декларации исполняемого блока определите переменную ename

типа employees.last_name%TYPE и переменную emp_sal типа

employees.salary%TYPE и инициализируйте ее с помощью подстановочной

переменной &sal.

c. В исполняемой секции выберите фамилии тех сотрудников, чьи зарплаты

равны знаечнию переменной emp_sal. Не используйте явных курсоров!

Если выборка вернет одну строку –добавьте в таблицу messages имя и

зарплату сотрудника.

d. Если для заданного значения зарплаты не найдено соответствующих

записей, обработайте соответствующую исключительную ситуацию, и

добавьте в таблицу messages запись «More than one employee with a salary of

<salary>».

DEFINE sal=6001

DECLARE

ename employees.last_name%type;

emp_sal employees.salary%type:=&sal;

BEGIN

DELETE messages;

SELECT last_name, salary INTO ename, emp_sal FROM employee_details WHERE salary = emp_sal;

IF SQL%rowcount=1 THEN

INSERT INTO messages (results) VALUES (ename || ' ' || emp_sal);

END IF;

EXCEPTION

WHEN NO_DATA_FOUND THEN

INSERT INTO messages (results) VALUES ('No employee with a salary of ' || emp_sal);

WHEN OTHERS THEN

INSERT INTO messages (results) VALUES ('More than one employee with a salary of ' || emp_sal);

END;

e. Просмотрите таблицу messages, чтобы оценить успешно или нет отработал

PL\SQL блок.

2. В этом упражнении вы посмотрите как создавать именованные исключения для

стандартных системных ошибок Oracle сервера ORA-02292 (нарушение

ограничений целостности).

a. В декларативной секции объявите childrecord_exists типа EXCEPTION.

Проассоциируйте эту переменную со стандартной ошибкой Oracle -02292.

Воспользуйтесь инструкцией PRAGMA EXCEPTION_INIT.

b. В исполняемой секции блока напечатайте сообщение «Deleting department

40........» и выполните инструкцию DELETE для удаления отедла с

department_id равным 40.

c. Добавьте секцию перехвата и обработки ошибок и поймайте в ней

childrecord_exists. При обработке ошибке выведите соответствующее

сообщение («Cannot delete this department. There are employees in this

department»).

DECLARE

childrecord_exists EXCEPTION;

PRAGMA EXCEPTION_INIT(childrecord_exists, -02292);

BEGIN

DBMS_OUTPUT.ENABLE();

DBMS_OUTPUT.PUT_LINE('Deleting department 40....');

DELETE departments WHERE department_id = 40;

EXCEPTION

WHEN childrecord_exists THEN

DBMS_OUTPUT.PUT_LINE('Cannot delete this department. There are employees in this department');

END;

3. Загрузите скрипт lab_07_04_soln.Sql.

a. В секции декларации внешнего блока убедитесь в наличии объявления

no_such_employee типа EXCEPTION.

b. Найдите комментарий «RAISE EXCEPTION HERE» в исполняемой секции

внешнего блока. Сразу после него проверьте что номер сотрудника попадает

в диапазон от 100 до 206. Если это не так, спровоцируйте no_such_employee

ошибку с помощью оператора RAISE.

c. Найдите комментарий: «INCLUDE EXCEPTION SECTION FOR OUTER

BLOCK». Сразу под комментарием добавьте необходимые инструкции для

обработки no_such_employee и too_many_rows ошибок. Для каждой ошибки

необходимо показывать соответствующее сообщение.

d. Зактройте OUTER блок.

e. Сохраниет скрипт под именем lab_08_03_soln.sql.

f. Запустите скрипт на исполнение. Введите номер сотрудника и номер отдела.

SET SERVEROUTPUT ON

SET VERIFY OFF

ACCEPT emp_id PROMPT 'Please enter your employee number';

ACCEPT emp_dept PROMPT 'Please enter the department number for which salary revision is being done';

DECLARE

emp_authorization NUMBER(5);

emp_id NUMBER(5):=&emp_id;

emp_deptid NUMBER(6):=&emp_dept;

no_such_employee EXCEPTION;

v_employee_id employee_details.employee_id%type;

-- INCLUDE EXECUTABLE SECTION OF OUTER BLOCK HERE

BEGIN

DBMS_OUTPUT.ENABLE();

-- RAISE EXCEPTION HERE

IF NOT emp_id BETWEEN 100 AND 206 THEN

RAISE no_such_employee;

END IF;

-- INCLUDE SIMPLE IF STATEMENT HERE

emp_authorization := emp_id;

IF emp_authorization = emp_id THEN

SELECT employee_id INTO v_employee_id FROM employee_details WHERE department_id IN (SELECT department_id FROM departments WHERE department_name = 'Human Resources');

DECLARE

emp_sal employee_details.salary%TYPE;

emp_fname employee_details.first_name%TYPE;

emp_lname employee_details.last_name%TYPE;

i NUMBER:=1;

-- DECLARE AN INDEX BY TABLE OF TYPE VARCHAR2(50). CALL

-- IT ename_table_type

TYPE ename_table_type IS TABLE OF VARCHAR2(50) INDEX BY BINARY_INTEGER;

ename_table ename_table_type;

-- DECLARE A VARIABLE ename_table OF TYPE ename_table_type

c_hike1 constant real :=.20;

c_hike2 constant real :=.15;

c_hike3 constant real :=.08;

c_hike4 constant real :=.03;

c_range1 constant number :=6500;

c_range2 constant number :=9500;

c_range3 constant number :=12000;

-- DECLARE A CURSOR CALLED emp_records TO HOLD salary,

-- first_name, and last_name of employees

CURSOR emp_records (emp_deptid NUMBER) IS SELECT salary, first_name, last_name FROM employee_details WHERE department_id=emp_deptid FOR UPDATE;

-- INCLUDE EXECUTABLE SECTION OF INNER BLOCK HERE

BEGIN

IF emp_deptid IN (20,60,80,100,110) THEN

DBMS_OUTPUT.PUT_LINE('SORRY, NO SALARY REVISIONS FOR EMPLOYEES IN THIS DEPARTMENT');

ELSE

OPEN emp_records (emp_deptid);

LOOP

FETCH emp_records INTO emp_sal, emp_fname, emp_lname;

IF emp_records%notfound THEN

EXIT;

ELSE

CASE

WHEN emp_sal<c_range1 THEN

ename_table(i):=emp_fname || ' ' || emp_lname;

i:=i+1;

UPDATE employee_details SET salary=emp_sal + (emp_sal*c_hike1) WHERE CURRENT OF emp_records;

WHEN emp_sal<c_range2 THEN

ename_table(i):=emp_fname || ' ' || emp_lname;

i:=i+1;

UPDATE employee_details SET salary=emp_sal + (emp_sal*c_hike2) WHERE CURRENT OF emp_records;

WHEN emp_sal<c_range3 THEN

ename_table(i):=emp_fname || ' ' || emp_lname;

i:=i+1;

UPDATE employee_details SET salary=emp_sal + (emp_sal*c_hike3) WHERE CURRENT OF emp_records;

ELSE

ename_table(i):=emp_fname || ' ' || emp_lname;

i:=i+1;

UPDATE employee_details SET salary=emp_sal + (emp_sal*c_hike4) WHERE CURRENT OF emp_records;

END CASE;

END IF;

END LOOP;

DBMS_OUTPUT.PUT_LINE('Number of records updated: '|| emp_records%rowcount);

CLOSE emp_records;

DBMS_OUTPUT.PUT_LINE(dept_id || ‘ ‘ || ename_table(k));

FOR k IN 1..i-1 LOOP

DBMS_OUTPUT.PUT_LINE(ename_table(k));

null;

END LOOP;

END IF;

-- CLOSE THE INNER BLOCK

END;

ELSE

DBMS_OUTPUT.PUT_LINE ('SORRY YOU ARE NOT AUTHORIZED TO USE THIS APPLICATION');

END IF;

-- INCLUDE EXCEPTION SECTION FOR OUTER BLOCK

EXCEPTION

WHEN no_such_employee THEN

DBMS_OUTPUT.PUT_LINE('No such employee');

WHEN too_many_rows THEN

DBMS_OUTPUT.PUT_LINE('Too many rows');

-- CLOSE THE OUTER BLOCK

END;

Протестируйте работу скрипта на разных входных значениях.

Emp_id

Dept_id

Result

100

100

SORRY, NO SALARY REVISIONS FOR EMPLOYEES IN THIS DEPARTMENT

50

100

No such employee

100

30

anonymous block completed

Number of records updated: 6

Den Raphaely

Alexander Khoo

Shelli Baida

Sigal Tobias

Guy Himuro

Karen Colmenares

Unknow error occured