2012-04-17 3 views
1

特定のテーブルのすべての列を更新しようとしています。 このテーブルには〜200,000,000レコードがあります。ROWIDのみを含むカーソルをループするpl/sqlを実行しようとしたときにエラーが発生しました

単純な更新ステートメントを実行しようとすると機能しません。私はそれを実行しようとする

DECLARE 
    TYPE ROW_ID_TBL IS TABLE OF ROWID; 
    CURSOR c_rowIdCursor RETURN ROWID IS 
     SELECT ROWID FROM SOME_TABLE; 

    v_RowIDs ROW_ID_TBL; 
BEGIN 
    OPEN c_rowIdCursor; 
    LOOP 
     FETCH c_rowIdCursor BULK COLLECT INTO v_RowIDs LIMIT 50000; 
     EXIT WHEN v_RowIDs.COUNT = 0; 

     FORALL i IN v_RowIDs.FIRST..v_RowIDs.LAST 
      UPDATE SOME_TABLE 
       SET SOME_KEY = MOD(NVL(REGEXP_REPLACE(ALPHA_NUMERIC_VAL, '[^0-9]+', ''), 0), 300)+1 
      WHERE ROWID = v_RowIDs(i); 
     COMMIT; 
    END LOOP; 
END; 
/

私は、次を得る:

ORA-06550: line 3, column 33: 
PLS-00320: the declaration of the type of this expression is incomplete or malformed 
ORA-06550: line 3, column 5: 
PL/SQL: Item ignored 
+0

すべての行が更新される前に 'SOME_KEY'がNULLになっていますか?そうであれば、簡単な 'UPDATE ... WHERE some_key IS NULLとROWNUM <= 50000'でこれを行うことができます。これをループに入れ、SQL%ROWCOUNTがゼロのときにループを終了します。 –

+0

それはあまりにも遅いです。私はすでにそれを試みました。それは4倍(3.7時間)を要した。 – ScrappyDev

+0

私のコメントは、パフォーマンスを犠牲にすることを意味する「メモリ不足」の問題を克服するためのものです。しかし、あなたの状況に適しているかもしれないし、そうでないかもしれない 'some_key'の適切な機能インデックスを使ってパフォーマンスの問題を克服することも可能です。 –

答えて

3

あなたCURSOR定義が間違っている

は、ここに私のコードです。あなたは何かが欲しい

CURSOR c_rowIdCursor 
    IS SELECT ROWID 
     FROM SOME_TABLE; 

もちろん、単純なアップデートがうまくいかない理由はわかりません。それは、より効率的で、より少ないリソースを使用し、より少ないコードを必要とするであろう。

+0

共有プールメモリが 'Xでセグメントを拡張できませんでした 'というエラーが発生しました。 – ScrappyDev

+0

@scrappythenell - 正確なエラーは何でしたか?一般的に、アップデートを分割すると同じエラーが発生します.1つのテーブルスペースの容量が足りないように思えます。 –

+0

私はそれが小さすぎるUNDO表領域だと思います。それを打ち破る。 – ScrappyDev

関連する問題