2016-07-24 100 views
1

同様の問合せに対する回答を見直しましたが、プロシージャが作成されたスキーマを追加することで解決できないような別のエラーが引き続き発生します。Oracle - ストアド・プロシージャを別のストアド・プロシージャのループで呼び出す

これは私が実行しようとしていますコードです:

create or replace procedure prcReturnDVD 
-- define the parameters that this proc will accept 
(memberid_in integer, dvd_in integer) 
is 
-- Define local variables 
    vNumRem number(2); 
BEGIN 
-- Update the rental table with the current date 
    update rental set rentalreturneddate = current_date where memberid = memberid_in and dvdid = dvd_in; 
-- update DVD quantityonhand to reflect the return 
    update dvd set dvdquantityonhand = dvdquantityonhand + 1 where dvdid = dvd_in; 
-- Check to see how many DVDs are available for rent for this member 
    select get_rentalsremaining(memberid_in) into vNumRem from dual; 
-- Evaluate the next action depending on number of remaining DVD rentals available 
    if vNumRem >= 1 then 
    -- need to write a for loop in order to cycle through the DVDs that need to be shipped out 
    while vNumRem >= 0 
    loop 
     SYSTEM.prcShipNextDVD(memberid_in); 
     vNumRem := vNumRem - 1; 
    end loop; 
    elsif vNumRem = 0 then 
    -- message that no rentals are allowed 
    dbms_output.put_line('No more rentals allowed.'); 
    end if; 

EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
    dbms_output.put_line('No Data Returned, process failed.'); 
    WHEN TOO_MANY_ROWS THEN 
    dbms_output.put_line('Too many rows returned into variable, check data and try again.'); 
    WHEN OTHERS THEN 
    dbms_output.put_line('An unidentified error has occured. Please research issue with procedure.'); 
END; 
/

それが唯一の宿題ですので、私は(私は唯一のシステムを使用している同じユーザによって以前書かれた別のプロシージャを呼び出すしようとしていますLOOP文内割り当てを簡略化します)。

create or replace procedure prcShipNextDVD 
-- define the parameters that this proc will accept 
(memberid_in integer) 
is 
-- Define local variables 
    vCountOut number(2); 
    vAllowedOut number(2); 
    vNextDvd number(16); 
    vAddedInQueue date; 
    vPlaceInQueue number(5); 
BEGIN 
-- ensure the member is eligible to take out another DVD at this time 
-- See how many movies the member currently has out 
    select count(*) into vCountOut from rental where memberid = memberid_in and rentalreturneddate is null; 
-- See how many movies the member is allowed to have out 
    select membershiplimitpermonth into vAllowedOut from membership m, member p where m.membershipid = p.membershipid and p.memberid = memberid_in; 
    IF vCountOut < vAllowedOut then 
    -- If the number out currently is less than the number allowed out currently 
    -- Get next DVD in queue available for shipment 
    select get_nextdvd(memberid_in) into vNextDVD, datedaddedinqueue into vAddedInQueue, rentalpriority into vPlaceInQueue from rentalqueue where memberid = memberid_in; 
    -- create new record in rental table for this shipment 
    insert into rental (rentalid, memberid, dvdid, rentalrequestdate, rentalshippeddate) values (rental_seq.nextval, memberid_in, vNextDVD, vAddedInQueue, current_date); 
    -- decrement dvdquantityon hand in dvd table 
    update dvd set quantityonhand = quantityonhand - 1 where dvdid = vNextDVD; 
    -- remove dvd from queue 
    delete from rentalqueue where memberid = memberid_in and dvdid = vNextDVD ; 
    -- manage remaining rentalpriority records by decrementing them properly (like in 2.1) 
    update rentalqueue set rentalpriority = rentalpriority - 1 where memberid = memberid_in and rentalpriority >= vPlaceInQueue; 
    ELSE 
    -- If the member already has the maximum number of movies out at this time 
    RAISE_APPLICATION_ERROR(-20101, 'Maximum number of movies out reached. You are not allowed to check out another movie at this time.'); 
    END IF; 

EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
    dbms_output.put_line('No Data Returned, process failed.'); 
    WHEN TOO_MANY_ROWS THEN 
    dbms_output.put_line('Too many rows returned into variable, check data and try again.'); 
    WHEN OTHERS THEN 
    dbms_output.put_line('An unidentified error has occured. Please research issue with procedure.'); 
END; 
/

プロシージャコールにスキーマ名を追加した後でも、次のエラーが発生します。私も "実行"と "呼び出し"でそれを実行しようとしましたが、それらが正しく動作しないことを知っています。

PROCEDURE PRCRETURNDVD compiled 
Errors: check compiler log 
19/7 PL/SQL: Statement ignored 
19/14 PLS-00905: object SYSTEM.PRCSHIPNEXTDVD is invalid 

私はこれについて間違っていますか?

私は呼び出しているがコンパイルに問題があります。 (コメント欄で概説したように)

+0

Oracleでは、同じプロシージャを異なるパラメータ・リストでコンパイルできます。したがって、同じ手順のいくつかの「バージョン」を保存することができます。これはオーバーロードと呼ばれます。たとえば、myadd(n1 pls_integer、n2 pls_integer)およびmyadd(n1 pls_integer、n2 pls_integer、n3 pls_integer)を使用でき、Oracleは両方のバージョンのプロシージャを保持します。エラーなしでコンパイルしたプロシージャーに、呼び出しようとしているものと同じパラメーター・タイプがあることを確認してください。トラブルシューティングのために、私はSQLコマンドラインから1つのストアドプロシージャを呼び出すだけで、他のプロシージャから呼び出すことはしません。 –

+0

私はあなたがパッケージ内以外で過負荷を行うことはできないと思うので、コンパイルした後、エラーが発生した場合は、エラーを表示するコマンドがあります。 prcshipnextdvdのコンパイルがきれいに戻ってきて、 "show errors"もきれいですか? –

+0

ヒットリターンが速すぎる...なぜこれが私にそれに続くエラーの原因になるのだろうか? レンタルからvCountOutにcount(dvdid)を選択します。ここで、memberid = memberid_inとrentalreturneddateはnullです; エラーは、カウントを行っている場所を指していて、ローカル変数の1つに配置しています。私はcount(*)&count(dvdid)を試してあいまいな参照の問題かどうかを確認しました。これらの数字は、どちらもまだ次のエラーが発生しています。 '20/5 PL/SQL:SQL文が無視されました ' ' 20/70 PL/SQL:ORA-00923:FROMキーワードが予期した場所に見つかりませんでした。' –

答えて

0

はprcShipNextDVDにコンパイルエラーを修正しました。

他のストアドプロシージャからの呼び出しが機能します。

+1

prcShipNextDVDコードを解析し、問題を引き起こしていた部分を正確に見つけました(エラーがどこから来たのか、約2つのステートメントがあります)。これが修正されれば、(いくつかの他の列名がスペルの間違いと修正された後に)問題なくコンパイルされ、その後、苦情なしにコンパイルされたprcShipNextDVDへの呼び出しで後続のprocがコンパイルされます。 ご理解いただきありがとうございます。 –

関連する問題