
- •Лабораторная работа № 3
- •1. Проанализируйте блок кода и ответьте на вопросы:
- •4. В этом задании вы будете работать с переменными подстановки, запрашивая их
- •Лабораторная работа № 4
- •3. С помощью инструкции update измените значение location_id, для вновь
- •4. Откройте скрипт lab_03_05b.Sql.
- •Лабораторная работа № 5
- •Лабораторная работа № 6
- •1. Напишите скрипт для распечатки информации о выбранной стране:
- •2. Напишите блок кода для выборки имени u1076 департамента из специальной структуры
- •3. Измените скрипт из второго пункта, таким образом, чтобы в индексированной таблице хранились записи (record), содержащие всю информацию об отделах.
- •Лабораторная работа № 7.
- •Лабораторная работа № 8.
- •1. Основная задача этого упражнения – продемонстрировать использование
- •3. Загрузите скрипт lab_07_04_soln.Sql.
Лабораторная работа № 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 |