Why RAISE_APPLICATION_ERROR() function is not working in this code? - plsql

I want to throw a customize error when the query fetches no record. But the below code is not throwing my desired error. It is throwing the system generated an error. Could you please help me? What mistake I am making?
DECLARE
v_em_id NUMBER := &var_id;
v_name varchar2(20);
BEGIN
SELECT first_name INTO v_name FROM employees WHERE employee_id =v_em_id;
IF SQL%NOTFOUND THEN
RAISE_APPLICATION_ERROR(-20002,'Employee not exist');
END IF;
DBMS_OUTPUT.PUT_LINE('Hi! '|| v_name);
END;
I should throw the error code:-20002
and error message: Employee not exist.

You can try the below code...
DECLARE
v_em_id NUMBER := &var_id;
v_name varchar2(20);
BEGIN
SELECT first_name INTO v_name FROM employees WHERE employee_id = v_em_id;
DBMS_OUTPUT.PUT_LINE('Hi! ' || v_name);
EXCEPTION
WHEN NO_DATA_FOUND THEN
IF SQL%NOTFOUND THEN
RAISE_APPLICATION_ERROR(-20002, 'Employee not exist');
END IF;
END;
If the select statement returns no rows it will raise no_data_found exception. So system is failing before the IF SQL%NOTFOUND THEN line..

SQL%NOTFOUND is useless here. If nothing is found, NO_DATA_FOUND exception is raised so you have to handle that. Here's an example based on Scott's schema:
SQL> declare
2 v_em_id number := &empno;
3 v_name varchar2(20);
4 begin
5 select ename
6 into v_name
7 from emp
8 where empno = v_em_id;
9
10 dbms_output.put_line('Hi, ' || v_name);
11 exception
12 when no_data_found then
13 raise_application_error(-20002, 'Employee does not exist');
14 end;
15 /
Enter value for empno: 7934
Hi, MILLER
PL/SQL procedure successfully completed.
SQL> /
Enter value for empno: 111
declare
*
ERROR at line 1:
ORA-20002: Employee does not exist
ORA-06512: at line 13
SQL>

Related

write a PLSQL block which will throw an exception if there is no record available in department table for the dept_id in emp table

schema details:
Table columns
dept dept_head, dept_id,dept_name ::::::
emp dept_id, emp_id,emp_lname, emp_status, loc_id, ...
output format:
Dept ID :**** is not a valid ID
I have tried with this code in HackerRank, getting the desired output still not able to pass the testcase. it says incorrect answer, testcase 0 failed. can anyone suggest me where i am making mistake and help me in passing the testcase.
set serveroutput on;
declare
DEPTID emp.DEPT_ID%type:=123;
DEPTNAME dept.DEPT_NAME%type;
DEPTHEAD dept.DEPT_HEAD%type;
begin
select DEPT_ID,DEPT_NAME,DEPT_HEAD into DEPTID,DEPTNAME,DEPTHEAD from dept where DEPT_ID=DEPTID;
DBMS_OUTPUT.PUT_LINE (DEPTID || DEPTNAME || DEPTHEAD);
Exception
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('Dept ID :'||DEPTID||' is not a valid ID');
END;
/
exit;
This should do it in principle:
begin
for r in (
select distinct dept_id from emp
)
loop
select dept_id into r.dept_id
from dept
where dept_id = r.dept_id;
end loop;
end;
A link to the Hackerrank question would be helpful to confirm what it's looking for.
Answer is --
set serveroutput on;
declare
DEPTID emp.DEPT_ID%type:=60;
DEPTNAME dept.DEPT_NAME%type;
DEPTHEAD dept.DEPT_HEAD%type;
begin
select DEPT_ID,DEPT_NAME,DEPT_HEAD into DEPTID,DEPTNAME,DEPTHEAD from dept where DEPT_ID=DEPTID;
DBMS_OUTPUT.PUT_LINE (DEPTID || DEPTNAME || DEPTHEAD);
Exception
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('Dept ID :'||DEPTID||' is not a valid ID');
END;
/
exit;
set serveroutput on;
declare
EMP_DEPTID emp.DEPT_ID%type;
DEPT_DEPTID DEPT.DEPT_ID%type;
cursor c is
select * from emp;
begin
for i in c loop
EMP_DEPTID:=i.DEPT_ID;
select d.DEPT_ID INTO DEPT_DEPTID FROM DEPT d where d.DEPT_ID=i.DEPT_ID;
end loop;
Exception
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('Dept ID :'||EMP_DEPTID||' is not a valid ID');
END;
/

Creating trigger in PL/SQL oracle 9

I'M trying to create a trigger based on the question on the image on the link below . but i'm struggling to handle duplicates on update and to handle maximum character length on insert and update. here is my solution.
CREATE OR REPLACE TRIGGER check_author
BEFORE UPDATE OR INSERT ON bk_author
FOR EACH ROW
DECLARE
v_authorid bk_author.authorid%type;
BEGIN
IF UPDATING THEN
IF LENGTH(:NEW.fname) > 10 THEN
RAISE_APPLICATION_ERROR(-20004,'Author name cannot exceed 10 characters');
END IF;
ELSIF INSERTING THEN
SELECT authorid
INTO v_authorid
FROM bk_author
WHERE authorid = :NEW.authorid;
RAISE_APPLICATION_ERROR(-20003,'Author id already existing cannot be added');
IF LENGTH(:NEW.fname) > 10 THEN
RAISE_APPLICATION_ERROR(-20004,'Author name cannot exceed 10 characters');
END IF;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Author '||:NEW.authorid||' added');
END;
/
You don't check condition to raise error about duplicate, it's executing no matter is there ID in database or not.
you should add IF before it
something like
ELSIF INSERTING THEN
SELECT authorid
INTO v_authorid
FROM bk_author
WHERE authorid = :NEW.authorid;
IF v_authorid is not null then
RAISE_APPLICATION_ERROR(-20003,'Author id already existing cannot be
added');
end if;
Try below code, it should work for you.
CREATE OR REPLACE TRIGGER check_author
BEFORE UPDATE OR INSERT ON bk_author
FOR EACH ROW
DECLARE
v_authorid number;
BEGIN
IF UPDATING THEN
IF LENGTH(:NEW.fname) > 10 THEN
RAISE_APPLICATION_ERROR(-20004,'Author name cannot exceed 10 characters');
END IF;
ELSIF INSERTING THEN
SELECT count(authorid) INTO v_authorid
FROM bk_author
WHERE authorid = :NEW.authorid;
DBMS_OUTPUT.PUT_LINE('Author id already existing cannot be added');
RAISE;
IF LENGTH(:NEW.fname) > 10 THEN
DBMS_OUTPUT.PUT_LINE('Author name cannot exceed 10 characters');
RAISE;
END IF;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Author '||:NEW.authorid||' added');
END;
/

Procedure error with '&'

error screenshot I am trying to execute the below program in Toad.
create or replace procedure tst_excp as
var_sal number;
var_empid number;
var_excp exception;
begin
select sal into var_sal from emp
where empno = &var_empid;
if var_sal < 4500 then
raise var_excp;
end if;
exception
when var_excp then
dbms_output.put_line ('The salary is low');
end;
and I am getting an error at the line: where empno = &var_empid;
error message is:
PL/SQL: ORA-00936: missing expression
I am planning to pass the value to the variable while executing it.
the & is part of the sqlplus (and TOAD, SQL Developer and PL/SQL Developer) runtime variables. it will prompt you on execution (in your case while compiling the procedure) for an input to replace in the code.
if you want the get an input for the procedure, so it will be added to the where clause on every run, you need to receive it as an input variable:
create or replace procedure tst_excp (var_empid in number) as -- << changed here
var_sal number;
var_empid number;
var_excp exception;
begin
select sal into var_sal from emp
where empno = var_empid; -- << changed here too
if var_sal < 4500 then
raise var_excp;
end if;
exception
when var_excp then
dbms_output.put_line ('The salary is low');
end;

No_data_found Exception handling

PROCEDURE getEmployeeDetails(EmpID IN NUMBER,
EmpSalary OUT NUMBER) Is
BEGIN
SELECT Salary
into EmpSalary
FROM Employee_accounts_master
WHERE Emp_ID = EmpID
AND SALARY = 'B';
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line(-20001);
When the above query fetches no rows, This procedure throws an NO_DATA_FOUND Exception. Instead of throwing this exception, I need to do some other update/insert process. How to achieve this.
Testing for the existence of records is one instance where explicit cursors can be useful.
PROCEDURE getEmployeeDetails(EmpID IN NUMBER,
EmpSalary OUT NUMBER)
IS
cursor c_emp (p_EmpID NUMBER) is
SELECT Salary
FROM Employee_accounts_master
WHERE Emp_ID = p_EmpID
AND SALARY = 'B';
r_Emp c_emp%rowtype;
BEGIN
open c_emp(EmpID);
fetch c_emp into r_emp;
if c_emp%NOTFOUND then
insert into employee (emp_id) values (EmpID);
end if;
close c_emp;
END;
Alternatively you can use a MERGE statement, but just coding a WHEN NOT MATCHED THEN INSERT branch. Find out more.
Just do it in exception section, check the below:
Begin
BEGIN
SELECT Salary
into EmpSalary
FROM Employee_accounts_master
WHERE Emp_ID = EmpID
AND SALARY = 'B';
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- use the label
goto myinsert;
end;
-- here is your line 67 code starts
<<myinsert>>
-- your insert statement, for eg.
insert into emp (empno) values (1);
end;

how to handle exception in if condition pl/sql

ineed your help when i wrote if else condition in plsql to check whether it is even or odd number using if conditopn . if i enter character then it will raise an error.how to handle it using exceptions to understand client. help me
declare
num number:=&number;
begin
if num=1 then
dbms_output.put_line('composite');
else if mod(num,2)=0 then
dbms_output.put_line('even');
else if mod(num,2)=1 then
dbms_output.put_line('odd');
else
dbms_output.put_line('enter proper data');
end if;
end if;
end if;
end;
/
Please see the following working example:
declare
-- user input is always a string so treat it as a string
v_input varchar2(32767) := '&number';
num number;
begin
-- convert input to a number. to_number() throws if input string can't be
-- converted to a number. see to_number() documentation for details.
-- the conversion has to happen inside begin-end block because the exception
-- handler of the block won't catch exceptions raised in declare block.
num:=to_number(v_input);
-- do your math
if num=1 then
dbms_output.put_line('composite');
elsif mod(num,2)=0 then
dbms_output.put_line('even');
elsif mod(num,2)=1 then
dbms_output.put_line('odd');
else
dbms_output.put_line('enter proper data');
end if;
exception
-- the exception raised by to_number()
when value_error then
dbms_output.put_line('not a valid number: ' || v_input);
-- all other exceptions are still raised to the caller.
end;
/
Example results:
SQL> #so
Enter value for number: 1
old 2: v_input varchar2(32767) := '&number';
new 2: v_input varchar2(32767) := '1';
composite
PL/SQL procedure successfully completed.
SQL> #so
Enter value for number: 2
old 2: v_input varchar2(32767) := '&number';
new 2: v_input varchar2(32767) := '2';
even
PL/SQL procedure successfully completed.
SQL> #so
Enter value for number: 3
old 2: v_input varchar2(32767) := '&number';
new 2: v_input varchar2(32767) := '3';
odd
PL/SQL procedure successfully completed.
SQL> #so
Enter value for number: foo
old 2: v_input varchar2(32767) := '&number';
new 2: v_input varchar2(32767) := 'foo';
not a valid number: foo
PL/SQL procedure successfully completed.
SQL>

Resources