SOLUTION MANUAL(Odd#)
CHAPTER 1
CODING EXERCISES
1.
SET SERVEROUTPUT ON
-- 6/3/2003
BEGIN
DBMS_OUTPUT.PUT_LINE('Name:John Smith');
DBMS_OUTPUT.PUT_LINE('Class:CMID563');
DBMS_OUTPUT.PUT_LINE('Semester:Summer 2003');
DBMS_OUTPUT.PUT_LINE('Session:1A2');
END;
/
|
3.
SET SERVEROUTPUT ON
DECLARE
var_dpt_name department.dpt_name%TYPE;
var_dpt_mgrssn department.dpt_mgrssn%TYPE;
var_dpt_mgr_start_date department.dpt_mgr_start_date%TYPE;
var_col VARCHAR2(20);
BEGIN
SELECT dpt_name, dpt_mgrssn, dpt_mgr_start_date
INTO var_dpt_name, var_dpt_mgrssn,
var_dpt_mgr_start_date
FROM department
WHERE dpt_no = &dept_number;
DBMS_OUTPUT.PUT_LINE('Department Name:' ||
var_dpt_name);
DBMS_OUTPUT.PUT_LINE('SSN of Department''s
Manager:' || var_dpt_mgrssn);
DBMS_OUTPUT.PUT_LINE('Manager''s start date:' ||
var_dpt_mgr_start_date);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('No data
found!');
END;
/
|
5.
SET SERVEROUTPUT ON
DECLARE
a NUMBER(10,2);
-- set the precision to 10 with 2 decimal
BEGIN
a := &b + &c * &d**2 - &e / 4;
DBMS_OUTPUT.PUT_LINE('a:' || a);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error!');
END;
/
|
CHAPTER 2
CODING EXERCISES
1.
SET
SERVEROUTPUT ON
DECLARE
v_date DATE :=
TO_DATE('&sv_user_date', 'DD-MM-YYYY');
v_day VARCHAR2(15);
BEGIN
v_day := RTRIM(TO_CHAR(v_date,
'DAY'));
IF v_day IN ('SATURDAY',
'SUNDAY') THEN
DBMS_OUTPUT.PUT_LINE(v_date||'
falls on weekend');
END IF;
- control resumes here
DBMS_OUTPUT.PUT_LINE('Done…');
END;
/
|
3.
SET
SERVEROUTPUT ON
DECLARE
v_final_grade NUMBER :=
&sv_num;
v_letter_grade CHAR(1);
BEGIN
IF v_final_grade BETWEEN 90
AND 100 THEN
v_letter_grade
:= 'A';
ELSIF v_final_grade BETWEEN 80
AND 89 THEN
v_letter_grade
:= 'B';
ELSIF v_final_grade BETWEEN 70
AND 79 THEN
v_letter_grade
:= 'C';
ELSIF v_final_grade BETWEEN 60
AND 69 THEN
v_letter_grade
:= 'D';
ELSE
v_letter_grade
:= 'F';
END IF;
-- control resumes here
DBMS_OUTPUT.PUT_LINE('Letter
grade is: '||v_letter_grade);
END;
/
|
5.
SET
SERVEROUTPUT ON
DECLARE
v_year number(4) :=
&sv_year;
BEGIN
IF MOD(v_year,100) = 0 THEN
IF
MOD(v_year,400) = 0 THEN
DBMS_OUTPUT.PUT_LINE(v_year
||' is a Century and leap year');
ELSE
DBMS_OUTPUT.PUT_LINE(v_year
||' is a Century and not a leap year');
END IF;
ELSIF MOD(v_year,4) = 0 THEN
DBMS_OUTPUT.PUT_LINE(v_year
||' is not a century but is a leap year');
ELSE
DBMS_OUTPUT.PUT_LINE(v_year
||' is not a century and not a leap year');
END IF;
DBMS_OUTPUT.PUT_LINE('Done…');
END;
/
|
7.
SET
SERVEROUTPUT ON
DECLARE
CURSOR mycur IS
SELECT * FROM
shipment;
total_value NUMBER(8,2) := 0;
myrow shipment%ROWTYPE;
BEGIN
OPEN mycur;
LOOP
FETCH mycur
INTO myrow;
EXIT WHEN
mycur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Description:
'|| myrow.description);
DBMS_OUTPUT.PUT_LINE('Price:
'|| myrow.itemrate);
DBMS_OUTPUT.PUT_LINE('Quantity
on hand: '|| myrow.qty_hand);
DBMS_OUTPUT.PUT_LINE('value:
'|| myrow.qty_hand* myrow.itemrate);
total_value :=
total_value + myrow.qty_hand * myrow.itemrate;
END LOOP;
CLOSE mycur;
DBMS_OUTPUT.PUT_LINE('Total
Value: '|| total_value);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('There
are no items in this table');
END;
/
|
9.
SET
SERVEROUTPUT ON
DECLARE
CURSOR cur_emp is
SELECT
emp_last_name, emp_middle_name, emp_first_name, emp_salary
FROM
employee, department
WHERE
emp_dpt_number = dpt_no
AND
dpt_name = 'Production'
ORDER
BY emp_first_name;
rec_emp cur_emp%rowtype;
BEGIN
DBMS_OUTPUT.PUT_LINE('Department:
Production');
OPEN cur_emp;
LOOP
FETCH cur_emp
INTO rec_emp;
EXIT WHEN
cur_emp%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Full
Name:' || rec_emp.emp_first_name || ' '
||
rec_emp.emp_middle_name || ' '
||
rec_emp.emp_last_name);
DBMS_OUTPUT.PUT('Salary:'
|| rec_emp.emp_salary);
IF rec_emp.emp_salary <= 30000 THEN
DBMS_OUTPUT.PUT_LINE('
(Class A)');
ELSIF
rec_emp.emp_salary BETWEEN 30000 AND 60000 THEN
DBMS_OUTPUT.PUT_LINE('
(Class B)');
ELSE
DBMS_OUTPUT.PUT_LINE('
(Class C)');
END IF;
END LOOP;
CLOSE cur_emp;
END;
/
|
11.
SET
SERVEROUTPUT ON
DECLARE
exp_not_found EXCEPTION;
v_day VARCHAR2(10);
var_counter INTEGER := 0;
CURSOR cur_emp is
SELECT
emp_last_name, emp_first_name, emp_middle_name, emp_date_of_birth
FROM
employee;
rec_emp cur_emp%rowtype;
BEGIN
OPEN cur_emp;
LOOP
FETCH cur_emp
INTO rec_emp;
EXIT WHEN
cur_emp%NOTFOUND;
v_day :=
RTRIM(TO_CHAR(rec_emp.emp_date_of_birth, 'DAY'));
IF v_day =
'TUESDAY' THEN
DBMS_OUTPUT.PUT_LINE('Full
Name:' || rec_emp.emp_first_name || ' '
||
rec_emp.emp_middle_name || ' '
||
rec_emp.emp_last_name);
var_counter
:= var_counter + 1;
END IF;
IF var_counter
= 2 THEN
EXIT;
END IF;
END LOOP;
CLOSE cur_emp;
IF var_counter <> 2 THEN
RAISE
exp_not_found;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Could
not find 2 employees born on Tuesday!');
WHEN exp_not_found THEN
DBMS_OUTPUT.PUT_LINE('Could
not find 2 employees born on Tuesday!');
END;
/
|
13.
SET
SERVEROUTPUT ON
DECLARE
sum_work_hours_planned assignment.work_hours_planned%TYPE
:= 0.0;
sum_work_hours assignment.work_hours%TYPE
:= 0.0;
CURSOR cur_dep is
SELECT dpt_no,
dpt_name, emp_last_name, emp_first_name, emp_middle_name
FROM
department DEP, employee EMP
WHERE
DEP.dpt_mgrssn = EMP.emp_ssn
ORDER BY
emp_first_name;
rec_dep cur_dep%rowtype;
CURSOR cur_pro(par_dept_number
department.dpt_no%TYPE) is
SELECT
pro_name
FROM project
WHERE
pro_dept_number = par_dept_number;
BEGIN
OPEN cur_dep;
LOOP
FETCH cur_dep
INTO rec_dep;
EXIT WHEN
cur_dep%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Department:
' || rec_dep.dpt_name);
DBMS_OUTPUT.PUT_LINE('Department
Manager:' || rec_dep.emp_first_name ||
'
' || rec_dep.emp_middle_name || ' ' || rec_dep.emp_last_name);
FOR rec_pro IN
cur_pro(rec_dep.dpt_no)
LOOP
DBMS_OUTPUT.PUT_LINE('Project
Name:' || rec_pro.pro_name);
END LOOP;
SELECT
SUM(work_hours), SUM(work_hours_planned)
INTO
sum_work_hours, sum_work_hours_planned
FROM
assignment
WHERE
work_pro_number in (
SELECT
pro_number
FROM
project
WHERE
pro_dept_number = rec_dep.dpt_no);
DBMS_OUTPUT.PUT_LINE('Total
work hours:' || sum_work_hours);
DBMS_OUTPUT.PUT_LINE('Total
work hours planned:' || sum_work_hours_planned);
DBMS_OUTPUT.PUT_LINE('**************************************');
END LOOP;
CLOSE cur_dep;
END;
/
|
15.
SET
SERVEROUTPUT ON
DECLARE
par_room_id bed.room_id%TYPE :=
'&room_id';
CURSOR cur_pat IS
SELECT
pat_last_name, pat_middle_name, pat_first_name, pat_id
FROM
patient PAT, bed BED
WHERE
PAT.bed_number = BED.bed_number
AND
room_id = par_room_id
ORDER
BY pat_first_name;
rec_pat cur_pat%rowtype;
CURSOR cur_staff(param1
patient.pat_id%type) is
SELECT
DISTINCT staff_first_name, staff_middle_name, staff_last_name
FROM
staff STF, treatment TRM
WHERE
STF.staff_id = TRM.staff_id
AND
pat_id = param1;
rec_staff cur_staff%rowtype;
BEGIN
DBMS_OUTPUT.PUT_LINE('Room
id:' || par_room_id);
OPEN cur_pat;
LOOP
FETCH cur_pat
INTO rec_pat;
EXIT WHEN
cur_pat%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Full
Name:' || rec_pat.pat_first_name || ' '
||
rec_pat.pat_middle_name || ' '
||
rec_pat.pat_last_name);
DBMS_OUTPUT.PUT_LINE('Treated
by:');
OPEN
cur_staff(rec_pat.pat_id);
LOOP
FETCH
cur_staff INTO rec_staff;
EXIT
WHEN cur_staff%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Staff
member''s Name:' || rec_staff.staff_first_name || ' '
||
rec_staff.staff_middle_name || ' '
||
rec_staff.staff_last_name);
END LOOP;
DBMS_OUTPUT.PUT_LINE('**************************************');
CLOSE
cur_staff;
END LOOP;
CLOSE cur_pat;
END;
/
|
17.
SET
SERVEROUTPUT ON SIZE 10000;
DECLARE
exc_exist EXCEPTION;
var_cnt NUMBER;
var_bol_exist BOOLEAN :=
FALSE; -- indicate if the situation where a patient is treated and prescribed
--
by the same staff member exists.
CURSOR cur_pre IS
SELECT
DISTINCT PRE.pat_id, PRE.staff_id, hospital_title,
staff_first_name,
staff_middle_name, staff_last_name,
pat_first_name,
pat_middle_name, pat_last_name
FROM
prescription PRE, staff STF, patient PAT
WHERE
PRE.staff_id = STF.staff_id
AND PAT.pat_id
= PRE.pat_id;
rec_pre cur_pre%ROWTYPE;
BEGIN
OPEN cur_pre;
LOOP
FETCH cur_pre
INTO rec_pre;
EXIT WHEN
cur_pre%NOTFOUND;
SELECT
count(*) INTO var_cnt
FROM
treatment
WHERE
pat_id = rec_pre.pat_id
AND
staff_id = rec_pre.staff_id;
IF var_cnt
> 0 THEN
var_bol_exist
:= TRUE;
DBMS_OUTPUT.PUT_LINE('Staff
member''s Name:' || rec_pre.staff_first_name ||
'
' || rec_pre.staff_middle_name || ' ' || rec_pre.staff_last_name);
DBMS_OUTPUT.PUT_LINE('Patient''s
Name:' || rec_pre.pat_first_name ||
'
' || rec_pre.pat_middle_name || ' ' || rec_pre.pat_last_name);
DBMS_OUTPUT.PUT_LINE('**************************************');
END IF;
END LOOP;
CLOSE cur_pre;
IF var_bol_exist THEN
RAISE
exc_exist;
END IF;
EXCEPTION
WHEN exc_exist THEN
DBMS_OUTPUT.PUT_LINE('Patient
treated and prescribed by same staff found!');
END;
/
|
19.
SET
SERVEROUTPUT ON
DECLARE
var_cnt INTEGER :=
0; -- indicate the number of prescriptions for a specific patient.
CURSOR cur_pat IS
SELECT
PRE.pat_id, pat_last_name, pat_middle_name, pat_first_name
FROM
prescription PRE, patient PAT
WHERE
PRE.pat_id = PAT.pat_id
GROUP
BY PRE.pat_id, pat_last_name, pat_middle_name, pat_first_name
HAVING
count(*) > 1;
rec_pat cur_pat%ROWTYPE;
CURSOR cur_last_update(param1
prescription.pat_id%TYPE) IS
SELECT
(SYSDATE - date_last_updated) date_diff
FROM
prescription
WHERE pat_id =
param1;
rec_last_update
cur_last_update%ROWTYPE;
BEGIN
OPEN cur_pat;
LOOP
FETCH cur_pat
INTO rec_pat;
EXIT WHEN
cur_pat%NOTFOUND;
OPEN
cur_last_update(rec_pat.pat_id);
LOOP
FETCH
cur_last_update INTO rec_last_update;
EXIT
WHEN cur_last_update%NOTFOUND;
IF
rec_last_update.date_diff < 7 AND rec_last_update.date_diff > 0 THEN
var_cnt
:= var_cnt + 1;
END
IF;
IF
var_cnt = 2 THEN
DBMS_OUTPUT.PUT_LINE('Patient''s
Name:' || rec_pat.pat_first_name ||
'
' || rec_pat.pat_middle_name || ' ' || rec_pat.pat_last_name);
EXIT;
END
IF;
END LOOP;
CLOSE
cur_last_update;
var_cnt := 0;
-- reset to 0 and start checking on another pat_id.
END LOOP;
CLOSE cur_pat;
END;
/
|
CHAPTER 3
CODING EXERCISES
1.
SET
SERVEROUTPUT ON
CREATE
OR REPLACE FUNCTION incr_salary(
ssn varchar2,percentage
NUMBER)
RETURN
NUMBER
IS
rsal NUMBER(10,2);
BEGIN
UPDATE employee
SET emp_salary = ((emp_salary
* percentage)/100+emp_salary)
WHERE emp_ssn=ssn;
SELECT emp_salary INTO rsal
FROM employee
WHERE emp_ssn = ssn;
RETURN (rsal);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Employee
not found ');
END
incr_salary;
|
3.
SET
SERVEROUTPUT ON
CREATE
OR REPLACE PROCEDURE emp_dept(
empno IN VARCHAR2,
deptname OUT VARCHAR2)
IS
BEGIN
SELECT dpt_name
INTO deptname FROM department
WHERE dpt_no =
(SELECT
emp_dpt_number FROM employee WHERE emp_ssn = empno) ;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Employee
or Dept does not exist ');
END
emp_dept;
|
5.
CREATE
OR REPLACE TRIGGER MYTRIG4
BEFORE
UPDATE ON EMPLOYEE FOR EACH ROW
BEGIN
IF (:NEW.EMP_SALARY <
20000) THEN
RAISE_APPLICATION_ERROR(21001,'SALARY
IS TOO LESS');
END IF;
END;
/
|
7.
CREATE
OR REPLACE PACKAGE pac_emp
AS
PROCEDURE
pro_find_emp(
par_emp_ssn IN employee.emp_ssn%TYPE,
par_full_name OUT VARCHAR2,
par_dept_no OUT department.dpt_no%TYPE);
FUNCTION
fun_get_salary(
par_emp_ssn employee.emp_ssn%TYPE,
par_percentage NUMBER)
RETURN NUMBER;
END
pac_emp;
/
CREATE
OR REPLACE PACKAGE BODY pac_emp
AS
PROCEDURE
pro_find_emp(
par_emp_ssn IN employee.emp_ssn%TYPE,
par_full_name OUT VARCHAR2,
par_dept_no OUT department.dpt_no%TYPE)
IS
var_emp_last_name
employee.emp_last_name%TYPE;
var_emp_middle_name
employee.emp_middle_name%TYPE;
var_emp_first_name
employee.emp_first_name%TYPE;
BEGIN
SELECT emp_last_name,
emp_middle_name, emp_first_name, emp_dpt_number
INTO
var_emp_last_name, var_emp_middle_name, var_emp_first_name, par_dept_no
FROM employee
WHERE emp_ssn
= par_emp_ssn;
par_full_name :=
var_emp_first_name || ' ' || var_emp_middle_name || ' ' || var_emp_last_name;
EXCEPTION
WHEN NO_DATA_FOUND then
par_full_name := null;
par_dept_no := -1;
END
pro_find_emp;
FUNCTION
fun_get_salary(
par_emp_ssn employee.emp_ssn%TYPE,
par_percentage NUMBER)
RETURN NUMBER
IS
ret_salary NUMBER(7,2);
BEGIN
SELECT emp_salary
INTO ret_salary
FROM employee
WHERE emp_ssn = par_emp_ssn;
ret_salary := ret_salary * (1
+ par_percentage / 100);
return (ret_salary);
EXCEPTION
WHEN NO_DATA_FOUND THEN
return (-1);
END
fun_get_salary;
END
pac_emp;
/
SET
SERVEROUTPUT ON
DECLARE
var_full_name employee.emp_first_name%type;
var_dpt_no department.dpt_no%type;
BEGIN
pac_emp.pro_find_emp('999666666',var_full_name,
var_dpt_no);
DBMS_OUTPUT.PUT_LINE(var_full_name || '
works in department ' || var_dpt_no);
DBMS_OUTPUT.PUT_LINE('His adjusted
salary is ' || fun_get_salary('999666666', 10));
END;
/
|
9.
CREATE
OR REPLACE FUNCTION fun_class(
par_ssn CHAR)
RETURN
VARCHAR
IS
ret_class VARCHAR2(10);
var_salary NUMBER(7,2);
BEGIN
SELECT emp_salary
INTO var_salary
FROM employee
WHERE emp_ssn = par_ssn;
IF var_salary <= 30000 THEN
ret_class
:='Class A';
ELSIF var_salary BETWEEN 30000
AND 60000 THEN
ret_class
:='Class B';
ELSE
ret_class
:='Class C';
END IF;
RETURN (ret_class);
EXCEPTION
WHEN NO_DATA_FOUND then
RETURN ('No Class');
END
fun_class;
/
|
11.
CREATE
OR REPLACE TRIGGER tri_start_date
BEFORE
INSERT OR UPDATE ON department FOR EACH ROW
BEGIN
IF
(RTRIM(TO_CHAR(:NEW.dpt_mgr_start_date, 'DAY')) IN ('SATURDAY', 'SUNDAY'))
THEN
RAISE_APPLICATION_ERROR(-20000,
'The start date cannot be on a Saturday or Sunday');
END IF;
END;
/
|
13.
DROP
TABLE lt_asgn_history;
DROP
TABLE asgn_history;
CREATE
TABLE lt_asgn_history (
work_emp_ssn CHAR(9),
work_pro_number NUMBER(2),
work_hours_completed NUMBER(5,1),
date_last_updated
DATE,
CONSTRAINT
pk_lt_asgn_history
PRIMARY KEY ( work_emp_ssn,
work_pro_number, date_last_updated),
CONSTRAINT
fk_lt_asgn_history
FOREIGN KEY (work_emp_ssn,
work_pro_number) REFERENCES assignment
)
;
CREATE
TABLE asgn_history (
work_emp_ssn CHAR(9),
work_pro_number NUMBER(2),
work_hours_completed NUMBER(5,1),
date_last_updated
DATE,
CONSTRAINT
pk_asgn_history
PRIMARY KEY ( work_emp_ssn,
work_pro_number, date_last_updated),
CONSTRAINT
fk_asgn_history
FOREIGN KEY (work_emp_ssn,
work_pro_number) REFERENCES assignment
)
;
CREATE
OR REPLACE TRIGGER tri_assg
AFTER
INSERT OR UPDATE OF work_hours_planned ON assignment
FOR
EACH ROW
BEGIN
IF :new.work_hours_planned = 0
THEN
IF
:new.work_hours >= 100 THEN
INSERT
INTO LT_ASGN_HISTORY (
work_emp_ssn,
work_pro_number, work_hours_completed, date_last_updated)
VALUES
(:new.work_emp_ssn, :new.work_pro_number,:new.work_hours, SYSDATE);
ELSE
INSERT
INTO ASGN_HISTORY (
work_emp_ssn,
work_pro_number, work_hours_completed, date_last_updated)
VALUES
(:new.work_emp_ssn, :new.work_pro_number,:new.work_hours, SYSDATE);
END IF;
END IF;
END;
/
UPDATE
assignment
SET
work_hours = 107.1, work_hours_planned = 0
WHERE
work_emp_ssn = '999333333' AND work_pro_number = 3;
UPDATE
assignment
SET
work_hours = 34, work_hours_planned = 0
WHERE
work_emp_ssn = '999222222' AND work_pro_number = 10;
|
No comments:
Post a Comment