0

手順を作成しようとしています。コードを実行すると、次のエラーが表示されます。

21/1     PLS-00103: Encountered the symbol "EXCEPTION" when expecting one
         of the following:
         ( begin case declare 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

おそらく、それは私BEGINEND文と関係がありますか?私はSQLが初めてで、理解できませんでした。

これが私のコードです:

CREATE OR REPLACE PROCEDURE inserttocasting(idofmovie  IN casting.movieid%TYPE,
                                            idofactor  IN casting.actorid%TYPE,
                                            newordinal IN casting.ordinal%TYPE)
IS
  identical_ordinal EXCEPTION;
  too_many_movies EXCEPTION;
BEGIN

  SELECT cast_year(idofmovie) INTO v_year FROM dual;

  IF ordinal_count(newordinal, idofmovie) >= 1 THEN
    RAISE identical_ordinal;
  ELSIF cast_count(v_year, idofactor) >= 3 THEN
    RAISE too_many_movies;
  ELSE
    INSERT INTO casting (movieid, actorid, ordinal)
    VALUES (idofmovie, idofactor, newordinal);
  END IF;

  EXCEPTION WHEN identical_ordinal THEN
    dbms_output.PUT_LINE('Ordinal already exists for this film!');

  EXCEPTION WHEN too_many_movies THEN
    DBMS_OUTPUT.PUT_LINE('This actor has already been cast in more than three movies this year.');
    COMMIT;
END;
/

必要に応じて使用される関数のコードを次に示します。

CREATE OR REPLACE FUNCTION ordinal_count(
newordinal IN CASTING.ORDINAL%TYPE, idofmovie IN CASTING.MOVIEID%TYPE
) RETURN NUMBER AS 
p_ordinal_number NUMBER;
BEGIN
SELECT COUNT(ACTORID)
INTO p_ordinal_number
FROM CASTING
WHERE ORDINAL = newordinal
AND MOVIEID = idofmovie;
RETURN p_ordinal_number;
END ordinal_count;
/
CREATE OR REPLACE FUNCTION cast_year(idofmovie IN CASTING.MOVIEID%TYPE
) RETURN NUMBER AS 
v_year NUMBER;
BEGIN
SELECT YEAR
INTO v_year
FROM MOVIE
WHERE MOVIEID = idofmovie;
RETURN v_year;
END cast_year;
/
CREATE OR REPLACE FUNCTION cast_count(v_year IN MOVIE.YEAR%TYPE, idofactor IN CASTING.ACTORID%TYPE
) RETURN NUMBER AS 
v_count NUMBER;
BEGIN
SELECT COUNT(v_year)
INTO v_count
FROM CASTING
WHERE ACTORID = idofactor;
RETURN v_count;
END cast_count;
/
4

1 に答える 1

0

最初の手順を次のように変更します。

CREATE OR REPLACE PROCEDURE insertToCasting(
  idofmovie IN CASTING.MOVIEID%TYPE,
  idofactor IN CASTING.ACTORID%TYPE,
  newordinal IN CASTING.ORDINAL%TYPE)
IS
  identical_ordinal EXCEPTION;
  too_many_movies EXCEPTION;
BEGIN
  SELECT cast_year(idofmovie)
    INTO v_year
    FROM dual;

  IF ordinal_count(newordinal, idofmovie) >= 1 THEN
    RAISE identical_ordinal;
  ELSIF cast_count(v_year, idofactor) >= 3 THEN
    RAISE too_many_movies;
  ELSE
    INSERT INTO CASTING (MOVIEID, ACTORID, ORDINAL)
      VALUES (idofmovie, idofactor, newordinal);

    COMMIT;
  END IF;
EXCEPTION
  WHEN identical_ordinal THEN
    DBMS_OUTPUT.PUT_LINE('Ordinal already exists for this film!');
  WHEN too_many_movies THEN
    DBMS_OUTPUT.PUT_LINE('This actor has already been cast in more than three movies this year.');
END;

複数の WHEN ブロックを 1 つの EXCEPTION ハンドラに入れることができます。また、ハンドラーの最後に COMMIT ステートメントがありましたWHEN too_many_movies...が、INSERT の後に続く必要があると思われます。配置された方法は、ハンドラーが入力された場合にのみ実行され、too_many_movies意味がないように思われました。

そして...空白を使ってください、ルーク... :-)

共有してお楽しみください。

于 2015-03-13T00:09:28.067 に答える