首页 > 技术文章 > 普通表转分区表的步骤

want990 2017-11-17 11:38 原文

1.添加Undo表空间(扩Undo表空间为了保证做数据迁移时UNDO空间不会爆掉)

--检查目前Undo表空间的名称及大小
 show parameter undo;
 select name,bytes/1024/1024 M from v$datafile where name like '%undo%';
--创建较大空间的Undo表空间
create undo tablespace UNDOTBS3 datafile '/opt/oracle/oradata/undotbs03.dbf' size 500m autoextend on;
--修改数据库默认Undo表空间为新的Undo表空间
 alter system set undo_tablespace=UNDOTBS3 scope=both;
--检查设置Undo表空间是否修改成功
show parameter undo;
--删除原有的Undo表空间(如数据库空间足够,不建议删除原有Undo表空间)
drop tablespace undotbs1 including contents and datafiles;

2.创建分区表

create table employee_par (
   EMPNO        NUMBER(15),
   ENAME        VARCHAR2(40),
   JOB          VARCHAR2(9),
   MGR          NUMBER(4),
   HIREDATE     DATE,
   SAL          NUMBER(7,2),
   COMM         NUMBER(7,2),
   DEPTNO       VARCHAR2(4)
)
PARTITION BY RANGE (HIREDATE)
(
  PARTITION t_employee_2004_less VALUES LESS THAN (TO_DATE('2004-01-01 00:00:00','yyyy-mm-

ddhh24:mi:ss')) TABLESPACE LXTBS2,
  PARTITION t_employee_2005_less VALUES LESS THAN (TO_DATE('2005-01-01 00:00:00','yyyy-mm-

ddhh24:mi:ss')) TABLESPACE LXTBS2,
  PARTITION t_employee_2006_less VALUES LESS THAN (TO_DATE('2006-01-01 00:00:00','yyyy-mm-

ddhh24:mi:ss')) TABLESPACE LXTBS2,
  PARTITION t_employee_2007_less VALUES LESS THAN (TO_DATE('2007-01-01 00:00:00','yyyy-mm-

ddhh24:mi:ss')) TABLESPACE LXTBS2,
  PARTITION t_employee_2008_less VALUES LESS THAN (TO_DATE('2008-01-01 00:00:00','yyyy-mm-

ddhh24:mi:ss')) TABLESPACE LXTBS2,
  PARTITION t_employee_2009_less VALUES LESS THAN (TO_DATE('2009-01-01 00:00:00','yyyy-mm-

ddhh24:mi:ss')) TABLESPACE LXTBS2,
  PARTITION t_employee_2010_less VALUES LESS THAN (TO_DATE('2010-01-01 00:00:00','yyyy-mm-

ddhh24:mi:ss')) TABLESPACE LXTBS2,
  PARTITION t_employee_2011_less VALUES LESS THAN (TO_DATE('2011-01-01 00:00:00','yyyy-mm-

ddhh24:mi:ss')) TABLESPACE LXTBS2,
  PARTITION t_employee_2012_less VALUES LESS THAN (TO_DATE('2012-01-01 00:00:00','yyyy-mm-

ddhh24:mi:ss')) TABLESPACE LXTBS2,
  PARTITION t_employee_2013_less VALUES LESS THAN (TO_DATE('2013-01-01 00:00:00','yyyy-mm-

ddhh24:mi:ss')) TABLESPACE LXTBS2,
  PARTITION t_employee_2014_less VALUES LESS THAN (TO_DATE('2014-01-01 00:00:00','yyyy-mm-

ddhh24:mi:ss')) TABLESPACE LXTBS2,
  PARTITION t_employee_2015_less VALUES LESS THAN (TO_DATE('2015-01-01 00:00:00','yyyy-mm-

ddhh24:mi:ss')) TABLESPACE LXTBS2,
  PARTITION t_employee_2016_less VALUES LESS THAN (TO_DATE('2016-01-01 00:00:00','yyyy-mm-

ddhh24:mi:ss')) TABLESPACE LXTBS2,
  PARTITION t_employee_2017_less VALUES LESS THAN (TO_DATE('2017-01-01 00:00:00','yyyy-mm-

ddhh24:mi:ss')) TABLESPACE LXTBS2,
  PARTITION t_employee_2018_less VALUES LESS THAN (TO_DATE('2018-01-01 00:00:00','yyyy-mm-

ddhh24:mi:ss')) TABLESPACE LXTBS2
)

3.写语句循环插入到新表中

declare
     v_empno number(15);
     v_ename varchar2(40);
     v_job       varchar2(9);
     v_mgr         number(4);
     v_hiredate  date;
     v_sal           number(7,2);
     v_comm     number(7,2);
     v_deptno    varchar2(4);
    v_length     number(8);
    v_sql        varchar(512);
    cursor loop_insert is  --创建游标
    select EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO from employee; 
    v_cur loop_insert%rowtype;
   begin
     v_length:=0; --定义批量插入自增变量
     for v_cur in loop_insert loop
        v_length:=v_length+1;
        v_empno:=v_cur.empno;
        v_ename:=v_cur.ename;
        v_job:=v_cur.job;
        v_mgr:=v_cur.mgr;
        v_hiredate:=v_cur.hiredate;
        v_sal:=v_cur.sal;
        v_comm:=v_cur.comm;
        v_deptno:=v_cur.deptno;
        --绑定变量方式插入
v_sql:='insert into employee_par nologging 
(empno,ename,job,mgr,hiredate,sal,comm,deptno) 
values(:1,:2,:3,:4,:5,:6,:7,:8)';
        execute immediate v_sql using 
v_empno,v_ename,v_job,v_mgr,v_hiredate,v_sal,v_comm,v_deptno;
        --5000条记录提交
if mod(v_length,5000)=0 then
           commit;
        end if;
      end loop;
      commit;
   end;
   / 

4.将老表改名成old

ALTER TABLE employee RENAME TO employee_old;

5.将分区表改为原表名

ALTER TABLE employee_par RENAME TO employee;  

6.删除老表

drop table employee_old;

 

enjoy :p

推荐阅读