Procedure to delete employee records from employee table - oracle

Create a procedure that deletes employee records from the Employee table. Get the department name as an input parameter. Delete the employee records who belongs to that department.
Display the count of employee records that were deleted. If the respective department was not found, then raise "DeptNotFoundException" and print the message 'No Records found.'
Assume the Employee table has been already created and a few records have been inserted.
EMPLOYEE:
Column name Data type Constraints
EMP_ID NUMBER(5) PK
EMP_NAME VARCHAR2(25) NOT NULL
SALARY NUMBER(10,2)
DEPT VARCHAR2(25)
EMP_ID EMP_NAME SALARY DEPT
------ -------- ------- -----
101 Tom 54000 MECH
102 William 43000 CSE
103 John 34560 MECH
104 Smith 56000 CSE
105 Steve 23450 IT
Functional Requirements:
PROCEDURE DELETE_EMPLOYEE( v_dept IN EMPLOYEE.dept%TYPE)
Sample Output:
2 Employee record(s) got deleted.
(Hint: Data is case sensitive. Use '/' to terminate the PLSQL block)
I have tried to solve this using my own logic, but it is showing error(out of 2 test only one is passed) can anyone point out the mistake?
set serveroutput on;
create or replace PROCEDURE DELETE_EMPLOYEE(v_dept IN EMPLOYEE.dept%TYPE)
is
temp number;
DEPTNOTFOUNDEXCEPTION Exception;
begin
select count(dept) into temp from EMPLOYEE where dept=v_dept;
delete from EMPLOYEE where dept=v_dept;
if temp>=1 then
dbms_output.put_line(temp||' Employee record(s) got deleted.');
else
raise DEPTNOTFOUNDEXCEPTION;
end if;
exception
when DEPTNOTFOUNDEXCEPTION then
dbms_output.put_line('No Records Found.');
end;
/

As others have pointed out, you can use SQL%ROWCOUNT and generally tidy up a bit but it doesn't look "wrong".
CREATE TABLE employee (
emp_id NUMBER(5) PRIMARY KEY
, emp_name VARCHAR2(25) NOT NULL
, salary NUMBER(10,2)
, dept VARCHAR2(25)
);
INSERT INTO employee (emp_id, emp_name, salary, dept) VALUES (101, 'Tom', 54000, 'MECH');
INSERT INTO employee (emp_id, emp_name, salary, dept) VALUES (102, 'William', 43000, 'CSE');
INSERT INTO employee (emp_id, emp_name, salary, dept) VALUES (103, 'John', 34560, 'MECH');
INSERT INTO employee (emp_id, emp_name, salary, dept) VALUES (104, 'Smith', 56000, 'CSE');
INSERT INTO employee (emp_id, emp_name, salary, dept) VALUES (105, 'Steve', 23450, 'IT');
DECLARE
dept_not_found EXCEPTION;
PROCEDURE delete_employee (p_dept IN employee.dept%TYPE) IS
BEGIN
DELETE employee
WHERE dept = p_dept;
IF SQL%ROWCOUNT = 0 THEN
RAISE dept_not_found;
END IF;
dbms_output.put_line(SQL%ROWCOUNT||' Employee record(s) got deleted.');
END delete_employee;
BEGIN
delete_employee('CSE');
delete_employee('ZZZ');
EXCEPTION
WHEN dept_not_found THEN
dbms_output.put_line('No Records Found.');
END;
/
2 Employee record(s) got deleted.
No Records Found.
PL/SQL procedure successfully completed.

Only an advice: Stop using raise when you want to output something. raise have always much more workload than:
if (sql%rowcount = 0) then
DBMS_Output.Put_Line('No Record Found');
return;
end if;

Related

Trigger DML in oracle database

I have problem with my dml trigger on oracle database.I want to launch trigger when i update first_name or last name on employees table in hr schema. During execution trigger i Have error ORA-00060: Please help. Idon't have any ideas how can i fix it.enter image description here
CREATE OR replace TRIGGER up_sal
BEFORE UPDATE OF first_name, last_name ON employees
FOR EACH ROW
DECLARE
PRAGMA autonomous_transaction;
var_sal employees.salary%TYPE;
var_avg NUMBER;
var_emp_id NUMBER;
BEGIN
SELECT salary
INTO var_sal
FROM employees
WHERE first_name = :NEW.first_name
OR last_name = :NEW.last_name;
SELECT Avg(salary)
INTO var_avg
FROM employees
WHERE department_id IN( :OLD.department_id );
IF var_sal < var_avg THEN
var_emp_id := :OLD.employee_id;
UPDATE employees
SET salary = var_avg * 1.1
WHERE employee_id = var_emp_id;
COMMIT;
END IF;
END;
You can use:
CREATE TRIGGER up_sal
BEFORE UPDATE OF first_name, last_name ON employees
FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
var_avg employees.salary%TYPE;
BEGIN
SELECT Avg(salary)
INTO var_avg
FROM employees
WHERE department_id IN( :OLD.department_id );
IF :NEW.salary < var_avg THEN
:NEW.salary := var_avg * 1.1;
END IF;
COMMIT;
END;
/
Which, for the sample data:
CREATE TABLE employees (
department_id NUMBER,
first_name VARCHAR2(20),
last_name VARCHAR2(20),
salary NUMBER
);
INSERT INTO employees (department_id, first_name, last_name, salary)
SELECT 1, 'Alice', 'Abbot', 90 FROM DUAL UNION ALL
SELECT 1, 'Betty', 'Baron', 95 FROM DUAL UNION ALL
SELECT 1, 'Carol', 'Count', 105 FROM DUAL UNION ALL
SELECT 1, 'Debra', 'Duke', 110 FROM DUAL;
Then if you do:
UPDATE employees
SET first_name = TRIM(first_name),
last_name = TRIM(last_name);
Then:
SELECT * FROM employees;
Outputs:
DEPARTMENT_ID
FIRST_NAME
LAST_NAME
SALARY
1
Alice
Abbot
110
1
Betty
Baron
110
1
Carol
Count
105
1
Debra
Duke
110
db<>fiddle here

delete rows from the employee table

Create a procedure that deletes rows from the employee table. it should accept 1 parameter, department name; only delete the employee records belonging to that department. display how many employees were deleted else raise "DeptNotFoundException" and print the message "No Records Found.".
Employee:
column name datatype constraints
EMP_ID NUMBER(5) PK
EMP_NMAE VARCHAR2(25) NOT NULL
SALARY NUMBER(10,2)
DEPT VARCHAR2(25)
EMP_ID EMP_NAME SALARY DEPT
101 JOHN 54000 MECH
102 TOM 43000 CSE
103 WILLIAM 34560 MECH
104 STEVE 56000 CSE
105 SMITH 23450 IT
and my code is,
set serveroutput on;
create or replace procedure delete_EMPLOYEE(dept_name in EMPLOYEE.dept%type) is
deptnotfound EXCEPTION;
begin
delete from EMPLOYEE where dept=dept_name;
if (sql%found) then
dbms_output.put_line(sql%rowcount || 'Employee record(s) got deleted.');
else
raise DeptNoFound;
end if;
EXCEPTION
when DeptNoFound then
dbms_output.put_line('No Records Found.');
end delete_EMPLOYEE;
/
it compiled successfully but not the test case. only 1 test case is passed instead of 2. can anyone help me out, please....
SET SERVEROUTPUT ON;
CREATE OR RPLACE PROCEDURE DELETE_EMPLOYEE(V_DEPT IN EMPLOYEE.DEPT%TYPE)
IS
DEPTNOTFOUNDEXCEPTION EXCEPTION;
BEGIN
DELETE FROM EMPLOYEE WHERE DEPT = V_DEPT;
IF SQL%FOUND THEN
DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT || ' EMPLOYEE RECORS(S) GOT DELETED.');
ELSE
RAISE DEPTNOTFOUNDEXCEPTION;
END IF;
EXCEPTION
WHEN DEPTNOTFOUNDEXCEPTION THEN
DBMS_OUTPUT.PUT_LINE('NO RECORDS FOUND.');
END;
/
You have declared exception deptnotfound and while raising it you have spelled it incorrectly as deptnofound.

Count the no of records

Write a program that gives all employees in Mechanical department,
(i) 15% pay increase.
(ii) display a message displaying how many employees were awarded the increase. if no Employees found then print the message 'No Records found'.
Employee :
columnname Data type constraints
EMPID NUMBER(5) PK
EMP_NAME VARCHAR(25) NOT NULL
SALARY NUMBER(10,2)
DEPT VARCHAR(25)
EMP_ID EMP_NAME SALARY DEPT
101 TOM 54000 MECH
102 WILLIAM 43000 CSE
103 JOHN 34560 MECH
104 SMITH 56000 CSE
105 STEVE 23450 IT
Sample Output : 2 Employee got increment.
and i did like this,
create or replace procedure empsal as
emp employee%rowtype;
sal number ;
cursor cr is select * from employees where dept='mech';
begin
open cr;
loop
fetch cr into emp;
exit when ce%notfound;
sal:=emp.salary+(emp.salary*15/100);
update employee set salary=sal where dept='mech';
end loop;
close cr;
if(sql%found) then
dbms_output.put_line(sql%rowcount);
else
dbms_output.put_line('no records found');
end;
but its shows the COMPILATION ERROR
No need to do make it that complex.
SQL> set serveroutput on
SQL> create or replace procedure empsal as
2 begin
3 update employee set
4 salary = salary * 1.15
5 where dept = 'MECH';
6
7 dbms_output.put_line(case when sql%rowcount = 0 then 'No records found'
8 else sql%rowcount || ' employees got increment'
9 end);
10 end;
11 /
Procedure created.
SQL> exec empsal;
2 employees got increment
PL/SQL procedure successfully completed.
SQL>
As of your compilation errors:
if table name is employee, don't use employees (while declaring a cursor)
if cursor name is cr, don't use ce for it (exit statement)
if misses end if
As of logical errors:
if department name is MECH, don't reference it as mech (letter case matters)
doing it in a loop - and without where clause in update statement - you're increasing salary for everyone as many times as there are employees in the MECH department.
in if, you're referencing a cursor that is already closed so ... no use of it

Table is mutating

after i insert this code, i got an error telling that
ORA-04091: table (schema).EMPLOYEES is mutating, trigger/function may not see it
ORA-06512: at "HR.TRGADDEMP_1215034", line 7
ORA-04088: error during execution of trigger 'HR.TRGADDEMP_1215034'
What should i do?
CREATE OR REPLACE TRIGGER TrgAddEmp_1215034
AFTER INSERT ON Employees
FOR EACH ROW
DECLARE
v_name varchar2(35);
v_managerName varchar2(20);
v_dept varchar2(35);
BEGIN
Select first_name||' '||last_name
INTO v_name
FROM Employees where employee_id = :new.employee_id;
Select last_name
into v_managerName
from employees where employee_id = :new.manager_id;
Select department_name
into v_dept
from departments where department_id = :new.department_id;
IF v_managerName is NULL THEN
DBMS_OUTPUT.PUT_LINE('There is a new employee '|| v_name );
DBMS_OUTPUT.PUT_LINE('The supervisor for this employee has not been decided');
DBMS_OUTPUT.PUT_LINE('This employee is assigned to '||v_dept|| 'Department');
ELSIF v_dept is NULL THEN
DBMS_OUTPUT.PUT_LINE('There is a new employee '|| v_name );
DBMS_OUTPUT.PUT_LINE('This employee is supervised by ' || v_managerName);
DBMS_OUTPUT.PUT_LINE('The department for this employee has not been decided');
ELSE
DBMS_OUTPUT.PUT_LINE('There is a new employee '|| v_name );
DBMS_OUTPUT.PUT_LINE('This employee is supervised by ' || v_managerName);
DBMS_OUTPUT.PUT_LINE('This employee is assigned to '||v_dept|| 'Department');
END IF;
END;
You should insert a correct code instead of this :)
ORA-4091 means that your triggers tried to select data from it's own table. Just don't do it. Never. Row-level triggers will not allow that.
This code tries to select a data which you already have.
Why you're trying to select first_name & last_name when you have :new.first_name and :new.last_name? And so on...

PL/SQL inserting a new record exception handling

I have an assignment in Oracle PL/SQL. I have to count the maximum number of employees working under a manager, and if this manager has more than 7 employees working under him I must raise an exception, which gives the message:
('Manager ||manager_name||' has maximium number of employees working under him'.)
Otherwise I must insert a new employee and give the message:
('It was inserted a new employee for the manager ||manager_name).
I have written the code, but I know something is wrong.
create table temp_emp as select * from employees;
select * from temp_emp;
create or replace procedure insert_emp(mngrId IN temp_emp.manager_id%type)
IS
ex_hugemp EXCEPTION;
emp_counter NUMBER;
fname temp_emp.first_name%type;
BEGIN
SELECT COUNT(*) INTO emp_counter
FROM temp_emp
WHERE temp_emp.manager_id=mngrId;
IF emp_counter > 7 THEN
RAISE ex_hugemp;
ELSE
INSERT INTO temp_emp(EMPLOYEE_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER
,HIRE_DATE, JOB_ID, SALARY, COMMISSION_PCT
,MANAGER_ID,DEPARTMENT_ID)
VALUES(LENGTH(EMPLOYEE_ID)+1, 'KAY', 'HORSTMAN', NULL, NULL
,'28-MAY-2013', 'IT_PROG', 24000, NULL, 103, 60);
DBMS_OUTPUT.PUT_LINE('It was inserted a new employee for the manager '||fname);
END IF;
EXCEPTION
WHEN ex_hugemp THEN
DBMS_OUTPUT.PUT_LINE('Manager '||fname||' has maximium number of employees working under him.');
END;
/
Your variable fname is empty. Fill it:
SELECT first_name
INTO fname
FROM temp_emp
WHERE employee_id = mngrid;
Use for the insert the same mngrid. Why is 103?
What is
LENGTH(EMPLOYEE_ID)+1
First: this will convert employee_id in string, get the length from the string and add 1. Do you really want this?. And second: you cannot use column name in values(). Create sequence (change 1 with your value to start):
CREATE SEQUENCE TEMP_EMP_SEQ START WITH 1;
and than use it in your procedure
temp_emp_seq.nextval
.
CREATE OR REPLACE PROCEDURE insert_emp (mngrid IN temp_emp.manager_id%TYPE) IS
ex_hugemp EXCEPTION;
emp_counter NUMBER;
fname temp_emp.first_name%TYPE;
BEGIN
SELECT first_name
INTO fname
FROM temp_emp
WHERE employee_id = mngrid;
SELECT COUNT (*)
INTO emp_counter
FROM temp_emp
WHERE temp_emp.manager_id = mngrid;
IF emp_counter > 7 THEN
RAISE ex_hugemp;
ELSE
INSERT INTO temp_emp (employee_id, first_name, last_name, email, phone_number, hire_date, job_id, SALARY,COMMISSION_PCT,MANAGER_ID,DEPARTMENT_ID)
VALUES( temp_emp_seq.nextval,'KAY','HORSTMAN',NULL,NULL,TO_DATE('28-05-2013','dd-mm-yyyy'),'IT_PROG',24000,NULL,mngrid,10);
DBMS_OUTPUT.put_line ('It was inserted a new employee for the manager ' || fname);
END IF;
EXCEPTION
WHEN ex_hugemp THEN
DBMS_OUTPUT.put_line ('Manager ' || fname || ' has maximium number of employees working under him.');
END;
/

Resources