Reputation: 93
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!
Upvotes: 3
Views: 1531
Reputation: 231851
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 be
ELSIF`.
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.
Upvotes: 3