2016-11-08 3 views
-1
set serveroutput on; 
DECLARE 
    CURSOR 
    IS 
    SELECT SVL_ID 
     FROM SALES_VEHICLES 
    WHERE SVL_N = 'some value';--314653; 

    TYPE SVD_TA IS TABLE OF VSALES%ROWTYPE; 
    SV SVD_TA; 
BEGIN 
    OPEN VSALES; 
    FETCH VSALES BULK COLLECT INTO SV LIMIT 1000; 
    CLOSE VSALES; 

    IF SV.COUNT() <> 0 
    THEN 
    FOR I IN 1..SV.COUNT() 
    LOOP 
     UPDATE SALES_VEHICLES 
      SET SVL_M = 'some value', 
       SVL_M = SVL_C_N 
     WHERE SVL_ID = I.SVL_ID; 

     COMMIT; 
    END LOOP; 
    END IF; 
    EXIT WHEN VSALES%NOTFOUND; 
    END LOOP; 
    CLOSE VSALES; 
END; 

これはデバッグに問題があります。エラーは32行目、5行目です。この問題で私を助けることができれば非常に感謝しています。ORA-06550:閉じるシンボルが発生しました

+1

カーソルを2回クローズしています。一度それを取得した後、そして一番最後に一度。しかし、あなたはまったくこのためにカーソルを使用していますか?プロシージャ全体を単一の 'update'ステートメントに置き換えることができます。**ステートメントは**ロット**より速く、次に行ごとのアプローチは遅くなります。 –

+0

私は、単一の更新ステートメントを使用しないように頼まれました。私はカーソルを1回だけ閉じることを試みましたが、私はまだORA 06550エラーを受けています(記号の終わりに遭遇しました) – ishan

+1

違反はありませんが、それは愚かな要求です。なぜ、ゆっくりとスケーラブルではないのですか? –

答えて

0

あなたは、二重近いライン15で間に合わ同じカーソルと32

を持っているおそらく、あなただけの取得後クローズする必要はありません。

BEGIN 
    OPEN VSALES; 
    LOOP 
    FETCH VSALES BULK COLLECT INTO SV LIMIT 1000; 

    IF SV.COUNT() <> 0 
    THEN 
    FOR I IN 1..SV.COUNT() 
    LOOP 
     UPDATE SALES_VEHICLES 
      SET SVL_M = 'some value', 
       SVL_M = SVL_C_N 
     WHERE SVL_ID = SV(I).SVL_ID;; 

     COMMIT; 
    END LOOP; 
    END IF; 
    EXIT WHEN VSALES%NOTFOUND; 
    END LOOP; 
    CLOSE VSALES; 
END; 
+0

カーソルを1回だけ閉じてみましたが、ORA 06550エラーが発生しました(シンボル終了時に発生) – ishan

+0

2つの 'end loop;と' loop'という2つの 'loop'もあります。カーソル@ishanを開いた後にループが見つからない可能性があります – Kacper

+0

私もそれを試しました。動いていない。私は試し続けます。ありがとう!!!! – ishan

0

解決策が見つかりました。私は以下を欠いていた。ここで私はこのことから

を変更するものです。これに

WHERE SVL_ID = I.SVL_ID; 

WHERE SVL_ID = SV(I).SVL_ID; 
0

は、必要以上に少し複雑そうです。

begin 
    for r in (
     select svl_id 
     from sales_vehicles 
     where svl_n = 'some value' --314653; 
    ) 
    loop 
     update sales_vehicles 
     set svl_m = 'some value', svl_m = svl_c_n 
     where svl_id = r.svl_id; 
    end loop; 

    commit; 
end; 

それとも、本当に配列(と、それはあなたがのために予想以上のメモリを取るだろうとチャンスを取る)を使用する場合:

declare 
    type svid_tt is table of sales_vehicles.svl_id%type; 
    l_svids svid_tt; 
begin 
    select svl_id bulk collect into l_svids 
    from sales_vehicles 
    where svl_n = 'some value';--314653; 

    if l_svids.count > 0 then 
     forall i in 1..l_svids.count 
      update sales_vehicles 
      set svl_m = 'some value', svl_m = svl_c_n 
      where svl_id = l_svids(i); 
    end if; 

    commit; 
end; 
をプレーンなカーソルループのために、あなただけのこれを行うことができます

リミット句とループを追加し、一括例外などをチェックすることで、アレイバージョンをより堅牢にすることができます。

関連する問題