2016-12-22 8 views
0

1つの列のデータを、10万のレコードを含む大きなテーブルの別の列にコピーしたい。 sys refcursorを使用して、ある列から別の列にデータをコピーしています。データのコピーには30分以上かかります。私はORACLE 11gR2を使用しています。大規模なテーブルoracleでのデータベース更新に膨大な時間がかかる

同じことを行う他の方法がありますか?以下は、あなたは正しい、tblのすべての行に対してこれをスクリプト


CREATE OR REPLACE PROCEDURE tblCursor(org_mig OUT SYS_REFCURSOR) 
IS 
    BEGIN 
    OPEN org_mig FOR 
    select id from tbl; 
    END; 
/
DECLARE 
    org_mig SYS_REFCURSOR; 
    t_id organization.id%TYPE; 
    loop_var number(10); 
    commit_interval number(10); 
BEGIN 
    loop_var :=1; 
    commit_interval:=10000; 
    tblCursor(org_mig); 

    LOOP 
    FETCH org_mig INTO t_id; 
    EXIT WHEN org_mig%NOTFOUND; 
    update tbl set col1=col2 where id=t_id; 
    IF mod(loop_var,commit_interval)=0 THEN 
     Commit; 
    End if; 
    loop_var :=loop_var+1; 
    END LOOP; 
    Commit; 
    CLOSE org_mig; 
END; 
/
+0

「ID」にはインデックスがありますか?私はあなたが何をしているのかは分かりませんが、データベース内のすべての行を更新するために時間がかかるので、一括挿入を使用する方が速くなるでしょう – Moudiz

答えて

1

やっているのですか?もしそうなら、あなただけのこの操作を行う必要があります。

update tbl 
set col1 = col2 
/

更新千万の行には少し時間がかかりますが、集合演算を使用すると、実装しました苦渋の行のアプローチにより、方法速く行以上になります。さらに、そのようなコミットをバッチアップするのは悪い習慣です。物事を遅くするだけでなく、そのアプローチはORA-01555: Snapshot too old例外につながる可能性があります。 Find out more

0
Still it has been taken long time to update. 


I am trying with different one but getting error. 

----------------------------------- 
Error starting at line : 43 in command - 
SELECT * 
FROM TABLE(test_parallel_update(CURSOR(SELECT * FROM organization))) 
Error report - 
SQL Error: ORA-12801: error signaled in parallel query server P003 
ORA-00932: inconsistent datatypes: expected - got - 
ORA-06512: at "QA249.TEST_PARALLEL_UPDATE", line 21 
12801. 00000 - "error signaled in parallel query server %s" 
*Cause: A parallel query server reached an exception condition. 
*Action: Check the following error message for the cause, and consult 
      your error manual for the appropriate action. 
*Comment: This error can be turned off with event 10397, in which 
      case the server's actual error is signaled instead. 

--------------------------- 
Here is the script: 




CREATE OR REPLACE TYPE test_num_arr AS TABLE OF NUMBER; 
CREATE OR REPLACE FUNCTION test_parallel_update (
    test_cur IN SYS_REFCURSOR 
) 
RETURN test_num_arr 
PARALLEL_ENABLE (PARTITION test_cur BY ANY) 
PIPELINED 
IS 
    PRAGMA AUTONOMOUS_TRANSACTION; 

    test_rec organization%ROWTYPE; 
    TYPE num_tab_t IS TABLE OF NUMBER(10,0); 
    TYPE vc2_tab_t IS TABLE OF number(1,0); 

    id NUM_TAB_T; 
    org_type_old NUM_TAB_T; 
    IS_DELETED_old VC2_TAB_T; 

    cnt INTEGER := 0; 
BEGIN 
    LOOP 
     FETCH test_cur BULK COLLECT INTO id, org_type_old, IS_DELETED_old LIMIT 1000; 
     EXIT WHEN id.COUNT() = 0; 

     FORALL i IN id.FIRST .. id.LAST 
      UPDATE organization 
      SET org_type = org_type_old(i) 
      ,  IS_DELETED = IS_DELETED_old(i) 
      WHERE id = id(i); 

     cnt := cnt + id.COUNT; 
    END LOOP; 

     CLOSE test_cur; 

    COMMIT; 
    PIPE ROW(cnt); 
    RETURN; 
END; 
/
show error; 
---- To Execute ---- 
SELECT * 
FROM TABLE(test_parallel_update(CURSOR(SELECT * FROM organization))); 



Note: 
Table 
organization 
(
id number(10,0), 
org_type number(10,0), 
org_type_old number(10,0), 
IS_DELETED number(1,0), 
IS_DELETED_OLD number(1,0) 
); 

where id is a primary key, Now I want copy org_type_old and IS_DELETED_OLD into org_type and IS_DELETED respectively. 
関連する問題