2017-01-16 12 views
0

2つのテーブル名を受け入れることができる動的プロシージャを作成しています.1つのテーブルからレコードを取得し、特定のレコードの後に​​(100レコードとします)、commitコマンドを発行する必要があります。 tabNameとtemp_tabNameの両方が常に同じです。最初のテーブルに何十億ものレコードがあるので、私は10000レコードごとにコミットして、UNDOテーブルスペースの問題を取り除いています。今私がやったティルレコードを動的に1つずつ取得するOracle

は次のとおりです。

CREATE OR REPLACE PROCEDURE MyProdecure (
     tabName  IN USER_TABLES.table_name%TYPE, 
     temp_tabName IN USER_TABLES.table_name%TYPE 
    ) 
    IS 
     v_sql   VARCHAR2 (100) := 'select * from ' || tabName; 
     TEMP_CURSOR SYS_REFCURSOR; 
     COUNT   NUMBER (6) := 0; 
    BEGIN 
     OPEN TEMP_CURSOR FOR v_sql; 

     LOOP 
      FETCH TEMP_CURSOR INTO V_ROW; 

     --================================================================================= 

     /* 
      * I need the code here to fetch the 100 record from TEMP_CURSOR into a Variable 
      * and insert into the second table. or one record increment the count and if 
      * count>= 100 commit 
      *What would be the data type of V_ROW. How to fetch the data from V_ROW and complete the insert into command. 
      */ 

     --================================================================================ 
      EXIT WHEN TEMP_CURSOR%NOTFOUND; 
     END LOOP; 

     CLOSE TEMP_CURSOR; 
    END MyProdecure; 
+0

私はそれがあなたが望むものであるかどうかはわかりませんが、{temp_cursor%rowcount = 100}を得るためにifを作ることができます。それはあなたが100行目を読むときにあなたを得るでしょう。 –

+0

なぜ1つずつですか?一度にセット全体を処理できないのはなぜですか? 100レコードごとに追加処理を行っていますか?あなたが追加の制約を持っていなければ、ループでこれを行うのは効率的ではないようです。 – xQbert

+3

これは宿題に関する質問ですか?一般に、バッチでコミットするのは良い方法ではありません。 – Boneist

答えて

0

、名前や構造知られていない入力テーブルのために正しくPL/SQLブロックを動作させるような方法でV_ROWを定義する方法はありません実行時まで

アプローチを機能させるには、DBMS_SQLを使用する必要があります。

UNDO世代の大部分をバイパスするために、次のバリエーションを検討しましたか?

CREATE OR REPLACE PROCEDURE MyProcedure (
     tabName  IN USER_TABLES.table_name%TYPE, 
     temp_tabName IN USER_TABLES.table_name%TYPE 
    ) 
    IS 
    l_log_io NUMBER; 
    C_BLOCK_SIZE NUMBER := 8192; -- assuming 8192 byte block size 
    l_undo_bytes NUMBER; 
BEGIN 
    EXECUTE IMMEDIATE 'INSERT /*+ APPEND */ INTO ' || temp_tabName || 
    ' SELECT * FROM ' || tabName; 

    select t.log_io, t.used_ublk*C_BLOCK_SIZE undo_bytes 
    into l_log_io, l_undo_bytes 
    from v$transaction t 
    where t.addr = (SELECT s.taddr FROM v$session s WHERE s.sid = USERENV('SID')); 

    dbms_output.put_line('Undo bytes used: ' || l_undo_bytes); 
END; 

INSERT /*+ APPEND */あなたがそれを使用する前になりますが、それはあなたの目標を達成するための非常にシンプルな方法かもしれない警告の数が付属しています。

関連する問題