3

OracleSPがコンパイルされない

私はMSSQLの経験がありますが、Oracleでクラスを受講していると、ストアドプロシージャのこのスクリプトが機能しない理由を理解できません。最初の例外変数の変数宣言セクションでエラーが発生します。エラーメッセージは次のとおりです。

 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

コード

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;
/

どんな助けでも大歓迎です!

4

1 に答える 1

3

私の仮定では、3つのINパラメーターの後で、他のすべてをプロシージャーのパラメーターとしてではなく、ローカル変数として宣言することを意図しています。プロシージャに例外を渡すことは意味がありません。あなたの' also needs to beELSEIFELSIF`。

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;
/

一般的な原則として、WHEN OTHERS例外を再発生させない例外ハンドラーは、ほぼ確実にエラーです。にデータを書き込んdbms_outputでも、そのデータが誰にでも見られたり、どこにでも保存されたりすることを保証するものではありません。だから、例えば

  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;

以前に発生した例外を再スローします。もちろん、処理できない例外を単にキャッチしなかった場合も、同じ動作が得られます。

于 2012-07-26T03:08:02.300 に答える