PLSQL Practice
PLSQL Practice
--PRACTICE-1
1) Which of the following PL/SQL blocks execute successfully?
a.BEGIN
END;
b.DECLARE
sal INTEGER(10);
END;
c.DECLARE
BEGIN
END;
d.DECLARE
total_sal INTEGER(10);
BEGIN
DBMS_OUTPUT.PUT_LINE(amount);
END;
Ans: c
2) Create and execute a simple anonymous block that outputs “Hello World.”
save this script as Introduction to PL/SQL 02_soln.sql.
begin
dbms_output.put_line('Hello World');
end;
/
--PRACTICE-2
Declaring Variables
3) Examine the following anonymous block and choose the appropriate statement.
DECLARE
v_fname VARCHAR2(20);
v_lname VARCHAR2(15) DEFAULT 'fernandez';
BEGIN
DBMS_OUTPUT.PUT_LINE(v_fname ||' ' ||v_lname);
END;
/
a. The block executes successfully and print “fernandez.”
b. The block returns an error because the fname variable is used without
initializing.
c. The block executes successfully and print “null fernandez.”
d. The block returns an error because you cannot use the DEFAULT keyword to
initialize a variable of type VARCHAR2.
e. The block returns an error because the v_fname variable is not declared.
declare
v_today DATE:=sysdate;
v_tomorrow v_today%type;
begin
v_tomorrow:=v_today+1;
dbms_output.put_line('Hello world');
dbms_output.put_line('today is :'||v_today);
dbms_output.put_line('Tomorrow is:'||v_tomorrow);
end;
/
--PRACTICE-3
1) Evaluate the preceding PL/SQL block and determine the data type and value of
each of the following variables according to the rules of scoping.
a.The value of weight at position 1 is:
2
The data type is NUMBER.
2) DECLARE
customer VARCHAR2(50) := 'Womansport';
credit_rating VARCHAR2(50) := 'EXCELLENT';
BEGIN
DECLARE
customer NUMBER(7) := 201;
name VARCHAR2(25) := 'Unisports'; BEGIN
credit_rating :=‘GOOD’;
END;
END;
In the preceding PL/SQL block, determine the values and data types for each of the
following cases.
3) Use the same session that you used to execute the practices in Lesson 2. If you
have opened a new session, then execute lab_02_05_soln.sql. Edit
lab_02_05_soln.sql.
a.Use single line comment syntax to comment the lines that create the bind
variables.
b.Use multiple line comments in the executable section to comment the lines that
assign values to the bind variables.
/*:basic percent:=50;
:pf percent :=20;*/
c.Declare two variables: fname of type VARCHAR2 and size 15, and emp_sal of type
NUMBER and size 10.
fname varchar2(15);
emp_sal number(10);
e.Change the line that prints “Hello World” to print “Hello” and the first name.
You can comment the lines that display the dates and print the bind variables, if
you want to.
dbms_output.put_line('Hello World'||fname);
4) Accept a value at run time using the substitution variable. In this practice,
you will modify the script lab_03_04.sql to accept user input.
a.Load the script lab_03_04.sql file.
b.Include the PROMPT command to prompt the user with the following message: “Please
enter your employee number.”
c.Modify the declaration of the empno variable to accept the user input.
empno number(6):=&empno;
SET SERVEROUTPUT ON
ACCEPT emp_id PROMPT 'Please enter your employee number';
ACCEPT emp_deptid 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_deptid;
no_such_employee EXCEPTION;
end;
/
--PRACTICE-4
1) Create a PL/SQL block that selects the maximum department ID in the departments
table and stores it in the max_deptno variable. Display the maximum department ID.
a.Declare a variable max_deptno of type NUMBER in the declarative section.
b.Start the executable section with the keyword BEGIN and include a SELECT
statement to retrieve the maximum department_id from the departments table.
c.Display max_deptno and end the executable block.
Execute and save your script as lab_04_01_soln.sql. Sample output is as follows:
declare
max_deptno number;
begin
select max(department_id) into max_deptno from departments;
dbms_output,put_line('the maximum department_id is :'||ma_deptno);
end;
/
2) Modify the PL/SQL block you created in exercise 1 to insert a new department
into the
departments table.
a.Load the script lab_04_01_soln.sql. Declare two variables: dept_name of type
departments.department_name. Bind variable dept_id of type NUMBER.
Assign ‘Education’ to dept_name in the declarative section.
b.You have already retrieved the current maximum department number from the
departments table. Add 10 to it and assign the result to dept_id.
:dept_id:=10+max_deptno;
dbms_output.put_line('SQL%ROWCOUNT gives'||SQL%ROWCOUNT);
e.Execute a select statement to check if the new department is inserted. You can
terminate the PL/SQL block with “/” and include the SELECT statement in your
script.
3) In exercise 2, you set location_id to null. Create a PL/SQL block that updates
the location_id to 3000 for the new department. Use the bind variable dept_id to
update the row.
Note: Skip step a if you have not started a new iSQL*Plus session for this
practice.
a.If you have started a new iSQL*Plus session, delete the department that you have
added to the departments table and execute the script lab_04_02_soln.sql.
b.Start the executable block with the keyword BEGIN. Include the UPDATE statement
to set the location_id to 3000 for the new department. Use the bind variable
dept_id in your UPDATE statement.
begin
update departments set location_id=3000
where department_id=:dept_id;
end;
/
c.End the executable block with the keyword END. Terminate the PL/SQL block with
“/” and include a SELECT statement to display the department that you updated.
begin
select employee_id into emp_authorization from
employee_details where department_id=(select department_id
from departments where department_name='Human Resources');
--PRACTICE-5
1) Execute the command in the file lab_05_01.sql to create the messages table.
Write a PL/SQL block to insert numbers into the messages table.
a.Insert the numbers 1 to 10, excluding 6 and 8.
b.Commit before the end of the block.
begin
for i in 1..10 loop
if i = 6 or i =8 then
null;
else
insert into message(results) values (i);
end if;
end loop;
commit;
end;
/
2) Execute the script lab_05_02.sql. This script creates an emp table that is a
replica of the employees table. It alters the emp table to add a new column, stars,
of VARCHAR2 data type and size 50. Create a PL/SQL block that inserts an asterisk
in the stars column for every
$1000 of the employee’s salary. Save your script as lab_05_02_soln.sql.
a.Use the DEFINE command to define a variable called empno and initialize it to
176.
DEFINE empno=176;
b.Start the declarative section of the block and pass the value of empno to the
PL/SQL block through an iSQL*Plus substitution variable. Declare a variable
asterisk of type emp.stars and initialize it to NULL. Create a variable sal of type
emp.salary.
c.In the executable section, write logic to append an asterisk (*) to the string
for every
$1000 of the salary. For example, if the employee earns $8000, the string of
asterisks should contain eight asterisks. If the employee earns $12500, the string
of asterisks should contain 13 asterisks.
declare
v_empno emp.employee_id%type:=to_number(&empno);
v_asterisk emp.stars%type:=null;
v_sal emp.salary%type;
begin
select nvl(round(salary/1000),0) into v_sal
from emp where employee_id=v_empno;
for i in 1..v_sal loop
v_asterisk:=v_asterisk||'*';
end loop;
end;
/
d.Update the stars column for the employee with the string of asterisks. Commit
before the end of the block.
update emp set stars=v_asterisk
where employee_id=v_empno;
commit;
e.Display the row from the emp table to verify whether your PL/SQL block has
executed successfully.
if(emp_id=emp_authorization) then
--PRACTICE-6
define countryid=CA
declare
country_record countries%rowtype;
begin
select * into country_record from countries
where country_id =upper('&countryid');
dbms_output.put_line('country id :' || country_record.country_id||
'country name:'||country_record.country_name||
'region:'||country_record.region_id);
end;
/
2) Create a PL/SQL block to retrieve the name of some departments from the
departments table and print each department name on the screen, incorporating an
INDEX BY table. Save the script as lab_06_02_soln.sql.
a.Declare an INDEX BY table dept_table_type of type departments.department_name.
Declare a variable my_dept_table of type dept_table_type to temporarily store the
name of the departments.
b.Declare two variables: loop_count and deptno of type NUMBER. Assign 10 to
loop_count and 0 to deptno.
c.Using a loop, retrieve the name of 10 departments and store
the names in the INDEX BY table. Start with department_id 10.
Increase deptno by 10 for every iteration of the loop.
The following table shows the department_id for which you
should retrieve the department_name and store in the INDEX BY table.
DEPARTMENT_ID DEPARTMENT_NAME
10 Administration
20 Marketing
30 Purchasing
40 Human Resources
50 Shipping
60 IT
70 Public Relations
80 Sales
90 Executive
100 Finance
d.Using another loop, retrieve the department names from the INDEX BY table and
display them.
e.Execute and save your script as lab_06_02_soln.sql. The output is as follows:
DECLARE
TYPE dept_table_type is table of departments.department_name%TYPE INDEX BY
PLS_INTEGER;
my_dept_table dept_table_type;
loop_count number(2):=10;
deptno number(4):=0;
BEGIN
FOR i IN 1..loop_count LOOP
deptno:=deptno+10;
SELECT department_name INTO my_dept_table(i)
FROM departments
WHERE department_id = deptno;
END LOOP;
3) Modify the block that you created in exercise 2 to retrieve all information
about each department from the departments table and display the information. Use
an INDEX BY table of records.
a.Load the script lab_06_02_soln.sql.
b.You have declared the INDEX BY table to be of type departments.department_name.
Modify the declaration of the INDEX BY table, to temporarily store the number,
name, and location of all the departments. Use the %ROWTYPE attribute.
c.Modify the select statement to retrieve all department information currently in
the
departments table and store it in the INDEX BY table.
d.Using another loop, retrieve the department information from the INDEX BY table
and display the information. Sample output is as follows
DECLARE
TYPE dept_table_type is table of departments%ROWTYPE INDEX BY PLS_INTEGER;
my_dept_table dept_table_type;
loop_count NUMBER (2):=10;
deptno NUMBER (4):=0;
BEGIN
FOR i IN 1..loop_count LOOP
deptno := deptno + 10; SELECT *
INTO my_dept_table(i) FROM departments
WHERE department_id = deptno;
END LOOP;
FOR i IN 1..loop_count LOOP
DBMS_OUTPUT.PUT_LINE ('Department Number: ' || my_dept_table(i).department_id
|| ' Department Name: ' || my_dept_table(i).department_name
|| ' Manager Id: '|| my_dept_table(i).manager_id
|| ' Location Id: ' || my_dept_table(i).location_id); END
LOOP;
END;
/
--PRACTICE-7
1) Create a PL/SQL block that determines the top n salaries of the employees.
a.Execute the script lab_07_01.sql to create a new table, top_salaries, for storing
the salaries of the employees.
b.Accept a number n from the user where n represents the number of top n earners
from the employees table. For example, to view the top five salaries, enter 5.
Note: Use the DEFINE command to define a variable p_num to provide the value for
n. Pass the value to the PL/SQL block through an iSQL*Plus substitution variable.
c.In the declarative section, declare two variables: num of type NUMBER to accept
the substitution variable p_num, sal of type employees.salary. Declare a cursor,
emp_cursor that retrieves the salaries of employees in descending order. Remember
that the salaries should not be duplicated.
d.In the executable section, open the loop and fetch top n salaries and insert them
into top_salaries table. You can use a simple loop to operate on the data. Also,
try and use %ROWCOUNT and %FOUND attributes for the exit condition.
DECLARE
num NUMBER(3) := &p_num;
sal employees.salary%TYPE;
CURSOR emp_cursor IS
SELECT distinct salary
FROM employees
ORDER BY salary DESC;
BEGIN
OPEN emp_cursor;
FETCH emp_cursor INTO sal;
WHILE emp_cursor%ROWCOUNT <= num AND emp_cursor%FOUND LOOP
INSERT INTO top_salaries (salary)
VALUES (sal);
FETCH emp_cursor INTO sal;
END LOOP;
CLOSE emp_cursor;
END;
e.After inserting into the top_salaries table, display the rows with a SELECT
statement. The output shown represents the five highest salaries in the employees
table.
SELECT * FROM top_salaries;
b.In the declarative section, declare a variable deptno of type NUMBER and assign
the value of p_deptno.
c.Declare a cursor, emp_cursor that retrieves the last_name, salary, and
manager_id of the employees working in the department specified in deptno.
d.In the executable section use the cursor FOR loop to operate on the data
retrieved. If the salary of the employee is less than 5000 and if the manager ID is
either 101 or 124, display the message <<last_name>> Due for a raise. Otherwise,
display the message <<last_name>> Not due for a raise.
declare
deptno number:=&p_deptno
cursor emp_cursor is
select last_name,salary,manager_id
from employees
where department_id=deptno;
begin
for emp_record in emp_cursor loop
if emp_record.salary<5000 and (emp_record.manager_id=101 or
emp_record.manager_id=124) then
dbms_output.put_line(emp_record.last_name||'due for a raise');
else
dbms_output.put_line(emp_record.last_name||'not due for a raise');
end if;
end loop;
end;
/
3) Write a PL/SQL block, which declares and uses cursors with parameters.
a.In a loop, use a cursor to retrieve the department number and the department name
from the departments table for a department whose department_id is less than 100.
Pass the department number to another cursor as a parameter to retrieve from the
employees table the details of employee last name, job, hire date, and salary of
those employees whose employee_id is less than 120 and who work in that department.
In the declarative section declare a cursor dept_cursor to retrieve department_id,
department_name for those departments with department_id less than 100. Order by
department_id.
DECLARE
CURSOR dept_cursor IS
SELECT department_id,department_name FROM departments
WHERE department_id < 100
ORDER BY department_id;
b.Declare another cursor emp_cursor that takes the department number as parameter
and retrieves last_name, job_id, hire_date, and salary of those employees with
employee_id of less than 120 and who work in that department
c.Declare variables to hold the values retrieved from each cursor. Use the %TYPE
attribute while declaring variables.
d.Open the dept_cursor, use a simple loop and fetch values into the variables
declared. Display the department number and department name.
e.For each department, open the emp_cursor by passing the current department number
as a parameter. Start another loop and fetch the values of emp_cursor into
variables and print all the details retrieved from the employees table.
Note: You may want to print a line after you have displayed the details of each
department. Use appropriate attributes for the exit condition. Also check if a
cursor is already open before opening the cursor.
f.Close all the loops and cursors, and end the executable section. Execute the
script.
current_deptno departments.department_id%TYPE;
current_dname departments.department_name%TYPE;
ename employees.last_name%TYPE;
job employees.job_id%TYPE;
hiredate employees.hire_date%TYPE;
sal employees.salary%TYPE;
BEGIN
OPEN dept_cursor;
LOOP
FETCH dept_cursor INTO current_deptno,current_dname;
EXIT WHEN dept_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE ('Department Number : ' ||
current_deptno ||
'Department Name : ' || current_dname);
IF emp_cursor%ISOPEN THEN CLOSE emp_cursor;
END IF;
OPEN emp_cursor (current_deptno); LOOP
FETCH emp_cursor INTO ename,job,hiredate,sal; EXIT WHEN emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE (ename || ' ' || job || ' ' || hiredate
|| ' ' || sal);
END LOOP;
DBMS_OUTPUT.PUT_LINE('--------------------------------------------------
--------------------------------------');
CLOSE emp_cursor;
END LOOP;
CLOSE dept_cursor;
END;
1) The purpose of this example is to show the usage of predefined exceptions. Write
a PL/SQL block to select the name of the employee with a given salary value.
a.Delete all the records in the messages table. Use the DEFINE command to define a
variable sal and initialize it to 6000.
b.In the declarative section declare two variables: ename of type
employees.last_name and emp_sal of type employees.salary. Pass the value of the
substitution variables to emp_sal.
c.In the executable section retrieve the last names of employees whose salaries are
equal to the value in emp_sal.
Note: Do not use explicit cursors.
If the salary entered returns only one row, insert into the messages table the
employee’s name and the salary amount.
d.If the salary entered does not return any rows, handle the exception with an
appropriate exception handler and insert into the messages table the message “No
employee with a salary of <salary>.”
e.If the salary entered returns more than one row, handle the exception with an
appropriate exception handler and insert into the messages table the message “More
than one employee with a salary of <salary>.”
f.Handle any other exception with an appropriate exception handler and insert into
the
messages table the message “Some other error occurred.”
g.Display the rows from the messages table to check whether the PL/SQL block has
executed successfully. Sample output is as follows:
select * from message;
2) The purpose of this example is to show how to declare exceptions with a standard
Oracle Server error. Use the Oracle server error ORA-02292 (integrity constraint
violated – child record found).
a.In the declarative section declare an exception childrecord_exists. Associate the
declared exception with the standard Oracle server error –02292.
b.In the executable section display “Deleting department 40. ”. Include a
DELETE
statement to delete the department with department_id 40.
c.Include an exception section to handle the childrecord_exists exception and
display the appropriate message. Sample output is as follows:
DECLARE
childrecord_exists EXCEPTION;
PRAGMA EXCEPTION_INIT(childrecord_exists, -02292);
BEGIN
DBMS_OUTPUT.PUT_LINE(' Deleting department 40. ');
delete from departments where department_id=40;
EXCEPTION
WHEN childrecord_exists THEN
DBMS_OUTPUT.PUT_LINE(' Cannot delete this department. There are employees in this
department (child records exist.)');
END;
/
--PRACTICE-9
1) In iSQL*Plus, load the script lab_02_04_soln.sql that you created for exercise 4
of practice 2.
a.Modify the script to convert the anonymous block to a procedure called greet.
b.Execute the script to create the procedure.
c.Save this script as lab_09_01_soln.sql.
d.Click the Clear button to clear the workspace.
e.Create and execute an anonymous block to invoke the procedure greet. Sample
output is as follows:
--PDF-5
--PRACTICE-I(Introduction)
a.Log in to the database by using the username and database connect string details
provided by your instructor (optionally, write the information here for your
records):
Username: ora
Password: ora
Database Connect String/Tnsname: t1
b.Execute basic SELECT statements to query the data in the DEPARTMENTS, EMPLOYEES,
and JOBS tables. Take a few minutes to familiarize yourself with the data, or
consult Appendix B, which provides a description and some data from each table in
the Human Resources schema.
SET SERVEROUTPUT ON
BEGIN
hello;
END;
/
DECLARE
total number := total_salary;
BEGIN
DBMS_OUTPUT.PUT_LINE('Total Salary: '|| total);
END;
/
a.Invoke the procedure and function that you created in exercises 2 and 3.
EXECUTE hello;
BEGIN
hello_again;
END;
/
--PRACTICE-1
1) Create and invoke the ADD_JOB procedure and consider the results.
a.Create a procedure called ADD_JOB to insert a new job into the JOBS table.
Provide the ID and title of the job using two parameters.
c.Invoke your procedure again, passing a job ID of ST_MAN and a job title of Stock
Manager. What happens and why?
a.Create a procedure called UPD_JOB to update the job title. Provide the job ID and
a new title using two parameters. Include the necessary exception handling if no
update occurs.
b.Compile the code; invoke the procedure to change the job title of the job ID
IT_DBA to
Data Administrator. Query the JOBS table to view the results.
3) Create a procedure called DEL_JOB to delete a job from the JOBS table.
Also, check the exception handling by trying to delete a job that does not exist.
(Use the IT_WEB job ID.) You should get the message that you used in the exception-
handling section of the procedure as output.
a.Create a procedure that returns a value from the SALARY and JOB_ID columns for a
specified employee ID. Compile the code and remove the syntax errors.
b. Execute the procedure using host variables for the two OUT parameters, one for
the salary and the other for the job ID. Display the salary and job ID for employee
ID 120.
BEGIN
get_employee(300,:salary,:job);
END;
/
--PRACTICE-2
a.Develop and store the function GET_ANNUAL_COMP, accepting parameter values for
monthly salary and commission. Either or both values passed can be NULL, but the
function should still return a non-NULL annual salary. Use the following basic
formula to calculate the annual salary:
(salary*12) + (commission_pct*salary*12)
b.Use the function in a SELECT statement against the EMPLOYEES table for employees
in department 30.
begin
select 1 into dummy from departments
where department_id=deptid;
return true;
exception
when no_data_found then
return false;
end valid deptid;
/
b.Create the ADD_EMPLOYEE procedure to add an employee to the EMPLOYEES table. The
row should be added to the EMPLOYEES table if the VALID_DEPTID function returns
TRUE; otherwise, alert the user with an appropriate message. Provide the following
parameters (with defaults specified in parentheses): first_name, last_name, email,
job (SA_REP), mgr (145), sal (1000), comm (0), and deptid (30). Use the
EMPLOYEES_SEQ sequence to set the employee_id column, and set hire_date to
TRUNC(SYSDATE).
CREATE OR REPLACE PROCEDURE add_employee(
first_name employees.first_name%TYPE,
last_name employees.last_name%type,
email employees.email%type,
job employees.job%type default 'SA_REP',
mgr employees.manager%type default 145,
sal employees.salary%type defauls 1000,
comm employees.commission_pct%type defauls 0,
deptid employees.department_id%type default 30) is
begin
if valid_deptid(deptid) then
insert into
employees(employee_id,first_name,last_name,email,job_id,manager_id,hire_date,salary
,commissiom_pct,department_id)
values (employees
seq.NEXTVAL,first_name,last_name,email,job,mgr,trunc(sysdate),sal,comm,deptid);
else
raise_application_error(-20204,'invalid department id. try again.');
end if;
end add_employee;
/
c.Call ADD_EMPLOYEE for the name Jane Harris in department 15, leaving other
parameters with their default values. What is the result?
Note: If the database server time is not between 8:00 and 18:00, the
Secure_employees trigger will be fired on performing any DML operation on the
EMPLOYEES table. Disable the aforesaid trigger to overcome this problem.
BEGIN
add_employee('Jane', 'Harris', 'JAHARRIS', deptid=> 15);
END;
d.Add another employee named Joe Harris in department 80, leaving the remaining
parameters with their default values. What is the result?
--PRACTICE-3
1.Create a package specification and body called JOB_PKG, containing a copy of your
ADD_JOB, UPD_JOB, and DEL_JOB procedures, as well as your GET_JOB function.
Tip: Consider saving the package specification and body in two separate files (for
example,
p3q1_s.sql and p3q1_b.sql for the package specification and body, respectively).
Include a SHOW ERRORS statement after the CREATE PACKAGE statement in each file.
Alternatively, place all code in one file.
Note: Use the code in your previously saved script files when creating the package.
a.Create the package specification including the procedures and function headings
as public constructs.
b.Create the package body with the implementations for each of the subprograms.
PROCEDURE upd_job(
jobid IN jobs.job_id%TYPE,
jobtitle IN jobs.job_title%TYPE) IS BEGIN
UPDATE jobs
SET job_title = jobtitle WHERE job_id = jobid;
IF SQL%NOTFOUND THEN
RAISE_APPLICATION_ERROR(-20202, 'No job updated.'); END IF;
END upd_job;
END job_pkg;
/
c.Invoke your ADD_JOB package procedure by passing the values IT_SYSAN and
Systems Analyst as parameters.
2.Create and invoke a package that contains private and public constructs.
a.Create a package specification and package body called EMP_PKG that contains your
ADD_EMPLOYEE and GET_EMPLOYEE procedures as public constructs, and include your
VALID_DEPTID function as a private construct.
Package specification:
Package body:
PROCEDURE add_employee(
first_name employees.first_name%TYPE, last_name employees.last_name%TYPE, email
employees.email%TYPE,
job employees.job_id%TYPE DEFAULT 'SA_REP', mgr employees.manager_id%TYPE DEFAULT
145, sal employees.salary%TYPE DEFAULT 1000,
comm employees.commission_pct%TYPE DEFAULT 0, deptid employees.department_id%TYPE
DEFAULT 30) IS
BEGIN
IF valid_deptid(deptid) THEN
INSERT INTO employees(employee_id, first_name, last_name, email,
job_id,manager_id,hire_date,salary,commission_pct,department_id)
VALUES (employees_seq.NEXTVAL, first_name, last_name, email, job, mgr,
TRUNC(SYSDATE), sal, comm, deptid);
ELSE
RAISE_APPLICATION_ERROR (-20204,
'Invalid department ID. Try again.');
END IF;
END add_employee;
PROCEDURE get_employee(
empid IN employees.employee_id%TYPE, sal OUT employees.salary%TYPE,
job OUT employees.job_id%TYPE) IS BEGIN
SELECT salary, job_id INTO sal, job
FROM employees
WHERE employee_id = empid; END get_employee;
END emp_pkg;
/
BEGIN
emp_pkg.add_employee('Jane', 'Harris','JAHARRIS', deptid => 15);
END;
EXECUTE emp_pkg.add_employee('David','Smith','DASMITH',deptid=>80)
--PRACTICE-10
1) The rows in the JOBS table store a minimum salary and a maximum salary allowed
for different JOB_ID values. You are asked to write code to ensure that employees’
salaries fall within the range allowed for their job type, for insert and update
operations.
a.Write a procedure called CHECK_SALARY that accepts two parameters, one for an
employee’s job ID string and the other for the salary. The procedure uses the job
ID to determine the minimum and maximum salary for the specified job. If the salary
parameter does not fall within the salary range of the job, inclusive of the
minimum and maximum, then it should raise an application exception, with the
message Invalid salary <sal>. Salaries for job <jobid> must be between
<min> and <max>. Replace the various items in the message with values supplied by
parameters and variables populated by queries. Save the file.
b.Create a trigger called CHECK_SALARY_TRG on the EMPLOYEES table that fires before
an INSERT or UPDATE operation on each row. The trigger must call the CHECK_SALARY
procedure to carry out the business logic. The trigger should pass the new job ID
and salary to the procedure parameters.
BEGIN
emp_pkg.add_employee('Eleanor', 'Beh', 30);
END;
UPDATE employees
SET salary = 2000
WHERE employee_id = 115;
UPDATE employees
SET job_id = 'HR_REP'
WHERE employee_id = 115;
UPDATE employees
SET salary = 2800
WHERE employee_id = 115;
3) Update the CHECK_SALARY_TRG trigger to fire only when the job ID or salary
values have actually changed.
a.Implement the business rule using a WHEN clause to check whether the JOB_ID or
SALARY values have changed.
Note: Make sure that the condition handles the NULL in the OLD.column_name
values if an INSERT operation is performed; otherwise, an insert operation will
fail.
BEGIN
emp_pkg.add_employee('Eleanor', 'Beh', 'EBEH',
job => 'IT_PROG', sal => 5000);
END;
/
c.Update employees with the IT_PROG job by incrementing their salary by $2,000.
What happens?
UPDATE employees
SET salary = salary + 2000
WHERE job_id = 'IT_PROG';
UPDATE employees
SET salary = 9000
WHERE employee_id = (SELECT employee_id
FROM employees
WHERE last_name = 'Beh');
e.Change the job of Eleanor Beh to ST_MAN using another UPDATE statement with a
subquery. What happens?
UPDATE employees
set job_id = 'ST_MAN'
WHERE employee_id = (SELECT employee_id
FROM employees
WHERE last_name = 'Beh');
4) You are asked to prevent employees from being deleted during business hours.
b.Attempt to delete employees with JOB_ID of SA_REP who are not assigned to a
department.
Note: This is employee Grant with ID 178.