oracle declare user defined exception - oracle

Oracle SP not compiling
I am expierenced at MS SQL but taking a class in Oracle and for the life of me cannot figure out why this script for a stored Procedure will not work. I am getting an error in the variable declaration section at the first Exception variable. here is the error message:
PLS-00103: Encountered the symbol "EXCEPTION" when expecting one of the following:
in out <an identifier> <a double-quoted delimited-identifier> LONG_ double ref char
time timestamp interval date binary national character nchar
The code
CREATE or REPLACE Procedure Movie_Rental_SP
(
Mv_ID IN Number,
Mem_ID IN Number,
Pay_ID IN Number,
Mv_Chk Number,
Mem_Chk Number,
Pay_Chk Number,
Qty_Chk Number,
--> next line is where the error points
UnKnown_Mv Exception,
UnKnown_Mem Exception,
UnKnown_Pay Exception,
UnAvail_Mv Exception )
IS
BEGIN
SELECT COUNT(Movie_ID) INTO Mv_Chk FROM MM_Movie WHERE Movie_ID = Mv_ID;
SELECT COUNT(Member_ID) INTO Mem_Chk FROM MM_Member WHERE Member_ID = Mem_ID;
SELECT COUNT(Payment_Methods_ID) INTO Pay_Chk FROM MM_Pay_Type WHERE Payment_Methods_ID = Pay_ID;
SELECT Movie_Qty INTO Qty_Chk FROM MM_Movie WHERE Movie_ID = Mv_ID;
IF Mv_Chk = 0 THEN RAISE UnKnown_Mv;
ELSE IF Mem_Chk = 0 THEN RAISE UnKnown_Mem;
ELSE IF Pay_Chk = 0 THEN RAISE UnKnown_Pay;
ELSE Qty_Chk = 0 THEN RAISE UnAvail_Mv;
END IF;
DECLARE New_ID NUMBER;
BEGIN
SELECT Max(Rental_ID)+1 INTO New_ID FROM MM_Rental;
EXCEPTION WHEN NO_DATA_FOUND THEN
New_ID := 1;
DBMS_OUTPUT.PUT_LINE ('There are no exsisting Rental IDs, ID set to 1');
END;
INSERT INTO MM_Rental VALUES (New_ID,Mem_ID,Mv_ID,Sysdate,Null,Pay_ID);
UPDATE MM_Movie SET Movie_Qty = Movie_Qty - 1 WHERE Movie_ID = Mv_ID;
EXCEPTION
WHEN UnKnown_Mv THEN
RAISE_APPLICATION_ERROR(-20001,'There is no movie with Movie ID of: '||Mv_ID||' Transaction cancelled.');
WHEN UnKnown_Mem THEN
RAISE_APPLICATION_ERROR(-20002,'No member exists with member ID: '||Mem_ID||' Transaction cancelled.');
WHEN UnKnown_Pay THEN
RAISE_APPLICATION_ERROR(-20003,'No payment type for: '||Pay_ID||' Transaction cancelled.');
WHEN UnAvail_Mv THEN
RAISE_APPLICATION_ERROR(-20004,'No movies available for: '||Mv_ID||' Transaction cancelled.');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE ('Error number: '||sqlcode);
DBMS_OUTPUT.PUT_LINE ('Error message: '||sqlerrm);
DBMS_OUTPUT.PUT_LINE('Unanticipated error. Contact your system administrator.');
END;
/
Any help would be greatly appreciated!

My assumption is that after the three IN parameters, your intention is to declare everything else as a local variable, not as parameters to the procedure. It wouldn't make sense to pass exceptions to a procedure. Your 'ELSE IFalso needs to beELSIF`.
CREATE or REPLACE Procedure Movie_Rental_SP
(
Mv_ID IN Number,
Mem_ID IN Number,
Pay_ID IN Number
)
AS
Mv_Chk Number;
Mem_Chk Number;
Pay_Chk Number;
Qty_Chk Number;
UnKnown_Mv Exception;
UnKnown_Mem Exception;
UnKnown_Pay Exception;
UnAvail_Mv Exception;
BEGIN
SELECT COUNT(Movie_ID) INTO Mv_Chk FROM MM_Movie WHERE Movie_ID = Mv_ID;
SELECT COUNT(Member_ID) INTO Mem_Chk FROM MM_Member WHERE Member_ID = Mem_ID;
SELECT COUNT(Payment_Methods_ID) INTO Pay_Chk FROM MM_Pay_Type WHERE Payment_Methods_ID = Pay_ID;
SELECT Movie_Qty INTO Qty_Chk FROM MM_Movie WHERE Movie_ID = Mv_ID;
IF Mv_Chk = 0 THEN RAISE UnKnown_Mv;
ELSIF Mem_Chk = 0 THEN RAISE UnKnown_Mem;
ELSIF Pay_Chk = 0 THEN RAISE UnKnown_Pay;
ELSE Qty_Chk = 0 THEN RAISE UnAvail_Mv;
END IF;
DECLARE
New_ID NUMBER;
BEGIN
SELECT Max(Rental_ID)+1 INTO New_ID FROM MM_Rental;
EXCEPTION WHEN NO_DATA_FOUND THEN
New_ID := 1;
DBMS_OUTPUT.PUT_LINE ('There are no exsisting Rental IDs, ID set to 1');
END;
INSERT INTO MM_Rental VALUES (New_ID,Mem_ID,Mv_ID,Sysdate,Null,Pay_ID);
UPDATE MM_Movie SET Movie_Qty = Movie_Qty - 1 WHERE Movie_ID = Mv_ID;
EXCEPTION
WHEN UnKnown_Mv THEN
RAISE_APPLICATION_ERROR(-20001,'There is no movie with Movie ID of: '||Mv_ID||' Transaction cancelled.');
WHEN UnKnown_Mem THEN
RAISE_APPLICATION_ERROR(-20002,'No member exists with member ID: '||Mem_ID||' Transaction cancelled.');
WHEN UnKnown_Pay THEN
RAISE_APPLICATION_ERROR(-20003,'No payment type for: '||Pay_ID||' Transaction cancelled.');
WHEN UnAvail_Mv THEN
RAISE_APPLICATION_ERROR(-20004,'No movies available for: '||Mv_ID||' Transaction cancelled.');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE ('Error number: '||sqlcode);
DBMS_OUTPUT.PUT_LINE ('Error message: '||sqlerrm);
DBMS_OUTPUT.PUT_LINE('Unanticipated error. Contact your system administrator.');
END;
/
As a general principle, a WHEN OTHERS exception handler that does not re-raise the exception is almost certainly an error. Writing data to dbms_output does not in any way guarantee that the data will be seen by anyone or persisted anywhere. So, for example
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE ('Error number: '||sqlcode);
DBMS_OUTPUT.PUT_LINE ('Error message: '||sqlerrm);
DBMS_OUTPUT.PUT_LINE('Unanticipated error. Contact your system administrator.');
RAISE;
will re-throw whatever exception was previously raised. Of course, you'd get the same behavior if you simply didn't catch exceptions that you can't handle.

Related

My program does not display the correct error message in Oracle database

I have this code
CREATE OR REPLACE PROCEDURE Insert_ord(
ID_CLIE IN CUSTOMERS.CUSTOMERID%TYPE,
NOMPROD IN products.productname%TYPE,
QUANTITY IN order_details.quantity%TYPE
)
IS
CHECKCLI INT;
CHECKPROD INT;
CHECKQTY INT;
ERR_CLI EXCEPTION;
ERR_PRODUCT EXCEPTION;
ERR_QTY EXCEPTION;
BEGIN
SELECT count(*) INTO CHECKCLI FROM customers WHERE customerid = ID_CLIE;
SELECT count(*) INTO CHECKPROD FROM PRODUCTS WHERE productname = NOMPROD;
SELECT unitsinstock-quantity INTO CHECKQTY FROM products WHERE productname = NOMPROD;
If CHECKCLI = 0 THEN
RAISE ERR_CLI;
ELSIF CHECKPROD = 0 THEN
RAISE ERR_PRODUCT;
ELSIF CHECKQTY < 0 THEN
RAISE ERR_QTY;
ELSE
DBMS_OUTPUT.PUT_LINE('NO ERRORS');
END IF;
EXCEPTION
WHEN ERR_CLI THEN
DBMS_OUTPUT.PUT_LINE('CLIENT DOESNT EXISTS');
WHEN ERR_PRODUCT THEN
DBMS_OUTPUT.PUT_LINE('PRODUCT DOESNT EXISTS');
WHEN ERR_QTY THEN
DBMS_OUTPUT.PUT_LINE('NOT ENOUGH PRODUCTS');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE || ':'|| SQLERRM);
END;
/
I want to display different error messages depending on the error, using the RISE function. When I execute CALL Insert_ord('WILMK','Flotemys', 20);, it should display the message "PRODUCT DOESNT EXISTS", but it shows me this message instead:
01403. 00000 - "no data found"
*Cause: No data was found from the objects.
*Action: There was no data from the objects which may be due to end of fetch.
So, it seems like the if statement is not working. Can someone help me, please?
When there are no records fetched from select statements, You will get the error as no data found. You need to use excpetion block to handle the no_data_found exception. Interestingly, When you use count function in select query, If there were no records, you will get the result as 0. So there is no need to use exception block with them. Your updated procedure will look alike -
CREATE OR REPLACE PROCEDURE Insert_ord(
ID_CLIE IN CUSTOMERS.CUSTOMERID%TYPE,
NOMPROD IN products.productname%TYPE,
QUANTITY IN order_details.quantity%TYPE
)
IS
CHECKCLI INT;
CHECKPROD INT;
CHECKQTY INT;
ERR_CLI EXCEPTION;
ERR_PRODUCT EXCEPTION;
ERR_QTY EXCEPTION;
BEGIN
SELECT count(*)
INTO CHECKCLI
FROM customers
WHERE customerid = ID_CLIE;
SELECT count(*)
INTO CHECKPROD
FROM PRODUCTS
WHERE productname = NOMPROD;
BEGIN
SELECT unitsinstock-quantity
INTO CHECKQTY
FROM products
WHERE productname = NOMPROD;
EXCEPTION
WHEN NO_DATA_FOUND THEN
CHECKQTY := 0;
END;
If CHECKCLI = 0 THEN
RAISE ERR_CLI;
ELSIF CHECKPROD = 0 THEN
RAISE ERR_PRODUCT;
ELSIF CHECKQTY < 0 THEN
RAISE ERR_QTY;
ELSE
DBMS_OUTPUT.PUT_LINE('NO ERRORS');
END IF;
EXCEPTION
WHEN ERR_CLI THEN
DBMS_OUTPUT.PUT_LINE('CLIENT DOESNT EXISTS');
WHEN ERR_PRODUCT THEN
DBMS_OUTPUT.PUT_LINE('PRODUCT DOESNT EXISTS');
WHEN ERR_QTY THEN
DBMS_OUTPUT.PUT_LINE('NOT ENOUGH PRODUCTS');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE || ':'|| SQLERRM);
END;
/

Exception error when creating procedure oracle sql developer

i have been whacking my brain for the past 2 hours can't find a solution to this error. I am creating a simple procedure to find an employee. PL/SQL keeps giving me error. What is the problem ? what am i doing wrong here ?
This is my Procedure:
create or replace PROCEDURE find_employee (employeeNo IN number) as
INVALID_ID exception;
TOO_MANY_ROWS exception;
res number;
BEGIN
dbms_output.enable;
Select count(*) into res from employee where ID=employeeNo;
if (res>1)then -- Checking that the total count of the employee is 1 or not
raise TOO_MANY_ROWS; -- if greater then 1 then it raise TOO_MANY_ROWS error
ELSE IF (NOT EXISTS (Select ID from employee where ID=employeeNo)) -- Checking that the employeeNo user passes exist or not
then
raise INVALID_ID; -- if employeeNo doesnot exit then display invalid id message
ELSE
Select* from Employee where ID=employeeNo; -- else return employee info whose id==employeeNo
END IF;
EXCEPTION
when TOO_MANY_ROWS then
DBMS_OUTPUT.PUT_LINE ('Too many Rows with same employee id');
when INVALID_ID then
DBMS_OUTPUT.PUT_LINE ('Invalid employee id');
END find_employee;
And error is this:
Error(15,1): PLS-00103: Encountered the symbol "EXCEPTION" when expecting one of the following: ( begin case declare end exit for goto if loop mod null pragma raise return select update while with <an identifier> <a double-quoted delimited-identifier> <a bind variable> << continue close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe purge
Error(20,18): PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following: end not pragma final instantiable order overriding static member constructor map
Please God Help me :'(
You're missing END IF (line #16). it is easier to spot it if you write formatted code (nested IF should have been indented).
SQL> create or replace PROCEDURE find_employee (employeeNo IN number) as
2 INVALID_ID exception;
3 TOO_MANY_ROWS exception;
4 res number;
5 BEGIN
6 dbms_output.enable;
7 Select count(*) into res from employee where ID=employeeNo;
8 if (res>1)then -- Checking that the total count of the employee is 1 or not
9 raise TOO_MANY_ROWS; -- if greater then 1 then it raise TOO_MANY_ROWS error
10 ELSE IF (NOT EXISTS (Select ID from employee where ID=employeeNo)) -- Checking that the employeeNo user passes exist or not
11 then
12 raise INVALID_ID; -- if employeeNo doesnot exit then display invalid id message
13 ELSE
14 Select* from Employee where ID=employeeNo; -- else return employee info whose id==employeeNo
15 END IF;
16 END IF; --> this is missing
17 EXCEPTION
18 when TOO_MANY_ROWS then
19 DBMS_OUTPUT.PUT_LINE ('Too many Rows with same employee id');
20 when INVALID_ID then
21 DBMS_OUTPUT.PUT_LINE ('Invalid employee id');
22 END find_employee;
As #Dornaut commented, that code probably isn't the best one could produce. Here's another option; see if it helps.
CREATE OR REPLACE PROCEDURE find_employee (employeeNo IN NUMBER)
AS
res NUMBER;
e_row employee%ROWTYPE;
BEGIN
SELECT *
INTO e_row
FROM employee
WHERE id = employeeNo;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.put_line ('Invalid employee ID');
WHEN TOO_MANY_ROWS
THEN
DBMS_OUTPUT.put_line ('Too many rows with same employee ID');
END find_employee;
So: if SELECT returns NO_DATA_FOUND or TOO_MANY_ROWS, it'll be handled. Otherwise, it'll fetch the whole row into a variable.

NO DATA FOUND oracle using cursor

I have been searching online using different solution suggestion to handle no data in this code but to no avail. how can I handle the exception if no data is found. How can I solve this problem. I am not an expert in oracle though!
DECLARE
nCheckOption INT;
no_data_found EXCEPTION;
CURSOR TYPE_cursor IS
SELECT
D_NAL_REF.TRANS
, D_NAL_REF.INJ
, D_NAL_REF.REF
FROM D_NAL_REF D_NAL_REF
WHERE D_NAL_REF.REF IN
(SELECT AG_REF.REF
FROM AG_REF A_REF
WHERE A_REF.DESCEND_REF = 10
);
BEGIN
FOR rec IN TYPE_cursor
LOOP
nCheckOption := 0;
SELECT 1
INTO nCheckOption
FROM PERSON_TYPE WHERE TRANS = rec.TRANS AND INJ = rec.INJ;
IF nCheckOption = 1 THEN
UPDATE PERSON_TYPE
SET PERSON_TYPE.TYPE = rec.REF
WHERE TRANS = rec.TRANS
AND PERSON_TYPE.INJ = rec.INJ;
END IF;
EXCEPTION
WHEN no_data_found
THEN
DBMS_OUTPUT.PUT_LINE ('Trapped the error!?');
END LOOP;
END;
/
Rewrite your code to eliminate the inner SELECT, which is the only place in your code where I can see that a NO_DATA_FOUND exception could possibly be raised:
BEGIN
FOR rec IN (SELECT d.TRANS,
d.INJ,
d.REF
FROM D_NAL_REF d
WHERE d.REF IN (SELECT a.REF
FROM AG_REF a
WHERE a.DESCEND_REF = 10) AND
(d.TRANS, d.INJ) IN (SELECT DISTINCT TRANS, INJ
FROM PERSON_TYPE))
LOOP
UPDATE PERSON_TYPE
SET TYPE = rec.REF
WHERE TRANS = rec.TRANS AND
INJ = rec.INJ;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE ('Trapped the error!?');
END;
I think you need to find if cursor contains any record or not. If cursor is empty then it must return that error message written in exception block.
Or you want to print error message if update statement do not find any record to update.
Here is the pseudo code.
Declare
ncheckoption number := 0;
Cursor type_cursor is ....
Begin
For rec in type_cursor loop
ncheckoption := ncheckoption + 1;
Update ...
If sql%rowcount = 0 then
Dbms_output.put_line('error message, if you want here in case no record found in table to update');
-- loop will continue
-- if you want loop to break then issue exit statement here
End if;
End loop;
If ncheckoption = 0 then
Dbms_output.put_line('error message you want to print in case cursor is empty');
End if;
End;
/
Cheers!!

Exception Handling SQL

I created a user defined function that calculates the quantity in stock for a product
CREATE OR REPLACE FUNCTION function_quantityInStock(
oldProductQuantity IN INTEGER,
orderedQuan IN INTEGER)
RETURN INTEGER
IS
v_newQuantity INTEGER;
v_oldQuantity INTEGER;
v_orderedQuan INTEGER;
BEGIN
v_newquantity := oldProductQuantity - orderedQuan;
RETURN v_newquantity;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Please check your data.');
END function_quantityInstock;
I then create a trigger that updates the table by calling the function
CREATE OR REPLACE TRIGGER TRIGGER_QUANTITY AFTER INSERT ON ordered_product
FOR EACH ROW
DECLARE
v_oldQuantity INTEGER;
BEGIN
SELECT PRODUCT_QUANTITYINSTOCK INTO v_oldQuantity
FROM product
WHERE product_id = :NEW.product_id;
UPDATE PRODUCT
SET product_quantityinstock =
function_quantityINSTOCK(v_oldQuantity, :NEW.ORDERED_PRODUCTQUANTITY)
WHERE product_id = :NEW.product_id;
END;
I want to display a message when the user enters invalid data but my exception block doesnt do that.
I use the following anonyomus block to test the function:
SET SERVEROUTPUT ON;
DECLARE
v_productID ordered_product.product_id%TYPE:= &ProductID;
v_orderID ordered_product.order_id%TYPE:=&OrderID;
v_orderedQuan ordered_product.ordered_productQuantity%TYPE := &OrderedProductQuantity;
v_totalCost ordered_product.ordered_productTotalCost%TYPE := '&TotalCost';
BEGIN
INSERT INTO ordered_product VALUES
(v_orderID, v_productID, v_orderedQuan, v_totalCost);
dbms_output.put_line('A new record has been inserted.');
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('Invalid data!');
WHEN VALUE_ERROR THEN
dbms_output.put_line('Error! Please check your values.'|| SQLERRM);
END;
You might be missing exec dbms_output.enable(10000) and therefore not be seeing the output.
You should throw the exception using
raise_application_error(-20000, 'Please check your data.');
Also it's bad practice to catch all exceptions using when others and then ignore them.
If I were you, I wouldn't rely on dbms_output.put_line to pass information around. Instead, rely on the standard exception handling, e.g. RAISE or RAISE_APPLICATION_ERROR. Also, given that you're trying to find the new quantity, I'd move the select on the product table into the function, something like:
CREATE OR REPLACE FUNCTION function_quantityinstock(p_product_id IN product.product_product_id p_orderedquan IN INTEGER)
RETURN INTEGER IS
v_newquantity INTEGER;
e_not_enough_stock EXCEPTION;
e_not_enough_stock_num INTEGER := -20001;
e_no_product_exists_num INTEGER := -20002;
PRAGMA EXCEPTION_INIT(e_not_enough_stock, -20001);
BEGIN
SELECT product_quantityinstock - orderedquan
INTO v_newquantity
FROM product
WHERE product_id = :new.product_id;
IF v_newquantity < 0
THEN
RAISE e_not_enough_stock;
END IF;
RETURN v_newquantity;
EXCEPTION
WHEN no_data_found THEN
raise_application_error(-e_no_product_exists_num,
'No product exists for product_id = ' || product_id);
-- no need to check for TOO_MANY_ROWS if product_id is the primary/unique key on the product table.
WHEN e_not_enough_stock THEN
raise_application_error(e_not_enough_stock_num,
'Not enough stock present to fulfil the order for product_id = ' ||
product_id);
WHEN OTHERS THEN
raise_application_error(SQLCODE,
'Unexpected error occurred whilst finding new quantity for product_id = ' ||
product_id || ': ' || SQLERRM);
END function_quantityinstock;
/
You'd need to change the function name though, to reflect the action that it's doing, since it's returning the new quantity in stock...

ora-01422 error by a procedure

Below code throwing ORA-01422 error. As my code uses select ... into I come to know it is fetching more than one row from the table but how can I overcome this by eliminating select into statement. Here is the code:
PROCEDURE Call_Transaction ( Transaction_Name Varchar2, Transaction_Type Varchar2, Form_Open_Type Varchar2 ) IS
BEGIN
Declare
M_Transaction_Name U_Transaction_Master.Transaction_Name%Type := Upper(Transaction_Name);
M_Transaction_Cd U_Transaction_Master.Transaction_Cd%Type;
T_Transaction_Cd U_Transaction_Master.Transaction_Cd%Type;
Begin
Select Transaction_Cd Into M_Transaction_Cd From U_Transaction_Master
Where Transaction_Name = M_Transaction_Name ;
Begin
Select Transaction_Cd Into T_Transaction_Cd From U_User_Wise_Transactions
Where Login_Cd = :Global.Login_Cd And Transaction_Cd = M_Transaction_Cd And
Inst_Cd = :Global.Company_Cd And
To_Char(Valid_Upto_Date,'DD-MM-YYYY') = '31-12-9999';
If Transaction_Type = 'FORM' And Upper(Form_Open_Type) = 'CALL_FORM' Then
DECLARE
id FormModule;
BEGIN
id := Find_Form(M_Transaction_Name); --<Replace your form name>--
IF Id_Null(id) THEN
Call_Form(:Global.Forms_Path||M_Transaction_Name||'.Fmx');
ELSE
Go_Form(Id) ;
END IF ;
END ;
Elsif Transaction_Type = 'FORM' And Upper(Form_Open_Type) = 'OPEN_FORM' Then
Open_Form(:Global.Forms_Path||M_Transaction_Name||'.Fmx');
Elsif Transaction_Type = 'REPORT' And Upper(Form_Open_Type) = 'RUN_PRODUCT' Then
Declare
Pl_Id ParamList;
Begin
Pl_Id := Get_Parameter_List('tmpdata');
IF NOT Id_Null(Pl_Id) THEN
Destroy_Parameter_List( Pl_Id );
END IF;
Pl_Id := Create_Parameter_List('tmpdata');
ADD_Parameter(pl_id,'Inst_Cd',TEXT_PARAMETER,:GLOBAL.Company_Cd);
ADD_Parameter(pl_id,'Ac_Year_Cd',TEXT_PARAMETER,:GLOBAL.Ac_Year_Cd);
ADD_Parameter(Pl_Id,'INST_NAME',TEXT_PARAMETER, :Global.Company_name);
ADD_Parameter(Pl_Id,'ADDRESS',TEXT_PARAMETER, :Global.Address);
ADD_Parameter(pl_id,'FOOTER',TEXT_PARAMETER,:GLOBAL.Footer);
Run_Product(REPORTS,:Global.Reports_Path||M_Transaction_Name, SYNCHRONOUS, RUNTIME,
FILESYSTEM, Pl_Id, NULL);
End;
End If;
Exception
When No_Data_Found Then
Message('Sorry..., You Do Not Have Authorization For : '||M_Transaction_Cd||' Transaction Code...');
Raise Form_Trigger_Failure;
End;
Exception
When No_Data_Found Then
Message('The Transaction Cd Not Exists In Transaction Master, Please Contact Administrator...');
Raise Form_Trigger_Failure;
End;
END;
How can I rewrite the code to resolve ORA-01422 error?
First, you need to change exception handling logic:
enclose in begin ... exception ... end only part that really can
through exception;
handle too_many_rows exception
.
PROCEDURE Call_Transaction ( Transaction_Name Varchar2, Transaction_Type Varchar2, Form_Open_Type Varchar2 ) IS
BEGIN
Declare
M_Transaction_Name U_Transaction_Master.Transaction_Name%Type := Upper(Transaction_Name);
M_Transaction_Cd U_Transaction_Master.Transaction_Cd%Type;
T_Transaction_Cd U_Transaction_Master.Transaction_Cd%Type;
Begin
-- 1st select with error analysis
begin
Select Transaction_Cd Into M_Transaction_Cd From U_Transaction_Master
Where Transaction_Name = M_Transaction_Name ;
exception
when No_Data_Found then begin
Message('The Transaction Cd Not Exists In Transaction Master, Please Contact Administrator...');
Raise Form_Trigger_Failure;
end;
when too_many_rows then begin
-- What really must be done in this case?
Message('There are too many Transaction Cd's with passed name In Transaction Master, Please Contact Administrator...');
Raise Form_Trigger_Failure;
end;
end;
-- 2nd select with error analysis
begin
Select Transaction_Cd Into T_Transaction_Cd From U_User_Wise_Transactions
Where Login_Cd = :Global.Login_Cd And Transaction_Cd = M_Transaction_Cd And
Inst_Cd = :Global.Company_Cd And
To_Char(Valid_Upto_Date,'DD-MM-YYYY') = '31-12-9999';
Exception
When No_Data_Found Then begin
Message('Sorry..., You Do Not Have Authorization For : '||M_Transaction_Cd||' Transaction Code...');
Raise Form_Trigger_Failure;
end;
When too_many_rows Then begin
-- What really must be done in this case?
Message('Sorry..., there are some misconfiguration in Authorization Settings For : '||M_Transaction_Cd||' Transaction Code. Please contact Administrator.');
Raise Form_Trigger_Failure;
end;
End;
If Transaction_Type = 'FORM' And Upper(Form_Open_Type) = 'CALL_FORM' Then
---[... all other code skipped ...]---
End If;
END;
After refactoring you need to answer a question about what really must be performed in situations when more than one row found and handle it according to nature of implemented task.
If you worried about method that you can use to detect presence of values and determine it's count then you may look at this question on StackOverflow.
In oracle, you can keep the select into statement and limit the number of rows using ROWNUM:
Select Transaction_Cd Into M_Transaction_Cd From U_Transaction_Master
Where Transaction_Name = M_Transaction_Name
and ROWNUM < 2;

Resources