如何删除ORA-01562:更新1亿行时无法扩展回滚段错误

时间:2017-08-23 09:41:41

标签: oracle plsql oracle-sqldeveloper plsqldeveloper

一张表有1亿条记录,我需要通过在每位员工的工资中加10%来更新一列。当我执行更新语句时,我收到此错误:

  

ORA-01562:无法扩展回滚段

如何更新此列以获得最佳效果?

update employee
set salary = salary + (salary*10/100)

OR

declare  
i number(10);
limit number(10) := 100000;
begin
for i in 1 .. limit loop 
update employee 
set salary = salary + (salary*10/100) 
where rownum = i; 
limit := limit + 100000; 
end loop;
end;

4 个答案:

答案 0 :(得分:1)

看起来您使用的是Oracle 8i版或更早版本,因为回滚段已被Oracle 9i以上的还原段替换。

要解决此问题,我建议您检查跟踪文件以查看哪个回滚段正在创建问题,然后根据更新事务大小创建更大的回滚段。

答案 1 :(得分:0)

试试这个:

DECLARE
   CURSOR CUR
   IS
      SELECT ROWID, A.*
        FROM YOUR_SALARY_TABLE A;

   TYPE CUR_TYPE IS TABLE OF CUR%ROWTYPE
      INDEX BY PLS_INTEGER;

   L_CUR   CUR_TYPE;

   LIM     NUMBER := 100000; -- Update chunk size
BEGIN
   OPEN CUR;

   LOOP
      FETCH CUR BULK COLLECT INTO L_CUR LIMIT LIM;

      FOR INDX IN 1 .. L_CUR.COUNT
      LOOP
         UPDATE YOUR_SALARY_TABLE S
            SET S.SALARY_COLUMN = S.SALARY_COLUMN * 2 -- Multiplying here
          WHERE ROWID = L_CUR (INDX).ROWID;
      END LOOP;

      COMMIT;

      EXIT WHEN L_CUR.COUNT < LIM;
   END LOOP;

   CLOSE CUR;
END;

答案 2 :(得分:0)

您可以尝试这种方法:link

有关并行的信息:link

答案 3 :(得分:0)

我们也可以使用FORALL来实现所需要的。希望下面的代码段有用。

DROP TABLE test_so1
/

CREATE TABLE TEST_SO1
  ( COL1 NUMBER, COL2 VARCHAR2(100)
  )
/

--Insert values
INSERT INTO TEST_SO1
SELECT LEVEL,'AVRAJIT'||LEVEL FROM DUAL CONNECT BY LEVEL < 10000
/

--FORALL UPDATE
DECLARE
type TEST_REC
IS
  RECORD
  (
    COL1 NUMBER,
    COL2 VARCHAR2(100),
    col3 VARCHAR2(100));
type TEST_TAB
IS
  TABLE OF TEST_REC;
  LV_TAB TEST_TAB;
  CURSOR LV_CUR
  IS
    SELECT col1,col2,rowid FROM TEST_SO1;
BEGIN
  OPEN LV_CUR;
  LOOP
    FETCH LV_CUR BULK COLLECT INTO LV_TAB LIMIT 1000;
    EXIT
  WHEN LV_TAB.COUNT=0;
    FORALL I IN LV_TAB.FIRST..LV_TAB.LAST
    UPDATE TEST_SO1 SET COL2 = 'shubhojit' WHERE ROWID = lv_tab(i).col3;
    COMMIT;
  END LOOP;
END;
/