Assn2Fall2010 Solution
Assn2Fall2010 Solution
Assn2Fall2010 Solution
Total: 8+5+(3+5+5)+6+6+6+6 = 50
1.
The EMP Table Structure Summary
EMP_NUM CHAR(3) (Must be a
number between 1 and
1000) (Primary Key)
EMP_LNAME VARCHAR2(15)
EMP_FNAME VARCHAR2(15)
EMP_INITIAL CHAR(1) (Must be a
char between ‘A’ and
‘Z’
EMP_HIREDATE DATE (NOT NULL)
JOB_CODE VARCHAR2(10)
(Foreign key to Job)
Given this information, write a script called a2q1.sql to answer the following
questions:
a. Write the SQL code that will create the table structures for Emp and Job .
CREATE TABLE emp(
emp_num CHAR(3) PRIMARY KEY,
emp_lname VARCHAR2(15),
emp_fname VARCHAR2(15),
emp_initial CHAR(1),
emp_hiredate DATE NOT NULL,
job_code VARCHAR2(10),
constraint check_emp_num
CHECK (emp_num between 1 and 1000),
constraint check_emp_initial
CHECK (emp_initial BETWEEN ‘A’ and ‘Z’)
constraint foreign_key_job
foreign key (job_code) references job(job_id)
);
(You can substitute my_table_name for JOB and EMP . Remember to give the
table names in CAPITAL letters).
a. The annual salary and the annual bonus percentage values are
defined using the DEFINE command.
b. Pass the values defined in the above step to the PL/SQL block
through SQL*Plus substitution variables . The bonus must be
converted from a whole number to a decimal (For example from 15
to .15) . If the salary is null, set it to zero before computing the total
compensation. Execute the PL/SQL block. Reminder : Use the NVL
function to handle NULL values .
DECLARE
v_salary NUMBER := &p_salary;
v_bonus NUMBER := &p_bonus;
v_total NUMBER;
BEGIN
/* NVL function takes 2 arguments a and b - sets the value to b if a is NULL*/
DECLARE
v_max_deptno NUMBER;
BEGIN
SELECT max(department_id)
INTO v_max_deptno
FROM departments;
:g_max_deptno := v_max_deptno;
END;
/
PRINT g_max_deptno
b. Modife the PL/SQL block created in 4.a. that inserts a new department into
the DEPARTMENT table.
DECLARE
v_max_deptno departments.department_id%TYPE;
BEGIN
SELECT MAX(department_id) + 10
INTO v_max_deptno
FROM departments;
COMMIT;
END;
/
SELECT *
FROM departments
WHERE department_name=’&p_dname’;
b. Create a PL/SQL block that deletes the department that you
created in 3.a and b.
DECLARE
v_result NUMBER(2);
BEGIN
DELETE
FROM departments
WHERE department_id = &p_deptno;
v_result := SQL%ROWCOUNT;
COMMIT;
END;
/
4. Use 3 substitution variables to store an employee number, the new
department number and the percentage increase in the salary and Create a
temporary table called emp which is a replica of table EMPLOYEES using the
following commands :
Update the department ID of the employee with the new department number, and
update the salary with the new salary. Use the EMP table for the updates. After
the update is complete, display the message, “Update complete” in the window. If
no matching records are found, display “No Data Found.”
BEGIN
UPDATE emp
SET department_id = &p_new_deptno,
salary = salary + salary * 0.01 * &p_per_increase
IF SQL%FOUND THEN
DBMS_OUTPUT.PUT_LINE('UPDATE COMPLETE');
ELSE
DBMS_OUTPUT.PUT_LINE('NO DATA FOUND');
END IF;
COMMIT;
END;
/
5. Create a PL/SQL block to declare a cursor EMP_CUR to select the employee
name, salary, and hire date from the employees table. Process each row from
the cursor, and if the salary is greater than 15,000 and the hire date is greater
than 01-FEB-1988, display the employee name, salary, and hire date in the
window in the format shown in the sample output below:
.
END IF;
FETCH EMP_CUR INTO ENAME,SAL,HIREDATE;
END LOOP;
CLOSE EMP_CUR;
END;
/
6. a. Create a PL/SQL block that declares a cursor called DATE_CUR. Pass a
parameter of DATE data type to the cursor and print the details of all the
employees who have joined after that date.
DECLARE
CURSOR DATE_CURSOR(JOIN_DATE DATE) IS
SELECT employee_id,last_name,hire_date FROM employees
WHERE HIRE_DATE >JOIN_DATE ;
EMPNO employees.employee_id%TYPE;
ENAME employees.last_name%TYPE;
HIREDATE employees.hire_date%TYPE;
HDATE employees.hire_date%TYPE := '&P_HIREDATE';
BEGIN
OPEN DATE_CURSOR(HDATE);
LOOP
FETCH DATE_CURSOR INTO EMPNO,ENAME,HIREDATE;
EXIT WHEN DATE_CURSOR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE (EMPNO || ' ' || ENAME || ' ' || HIREDATE);
END LOOP;
END;
/
7. In a loop, use a cursor to retrieve the department number and the department
name from the DEPARTMENTS table for those departments whose
DEPARTMENT_ID is less than 100. Pass the department number to another
cursor to retrieve from the EMPLOYEES table the details of emplyee last name,
job, hire date, and salary of those employees whose EMPLOYEE_ID is less than
120 and who work in that department.
v_current_deptno departments.department_id%TYPE;
v_current_dname departments.department_name%TYPE;
v_ename employees.last_name%TYPE;
v_job employees.job_id%TYPE;
v_hiredate employees.hire_date%TYPE;
v_sal employees.salary%TYPE;
v_line varchar2(100);
BEGIN
OPEN dept_cursor;
LOOP
FETCH dept_cursor INTO v_current_deptno, v_current_dname;
EXIT WHEN dept_cursor%NOTFOUND;
IF emp_cursor%ISOPEN THEN
CLOSE emp_cursor;
END IF;
OPEN emp_cursor(v_current_deptno);
LOOP
DBMS_OUTPUT.PUT_LINE( v_ename ||
' ' ||
v_job ||
' ' ||
v_hiredate||
' ' ||
v_sal);
END LOOP;
IF emp_cursor%ISOPEN THEN
CLOSE emp_cursor;
END IF;
END LOOP;
IF emp_cursor%ISOPEN THEN
CLOSE emp_cursor;
END IF;
CLOSE dept_cursor;
END;
/