plsql 导出分区_批量move table(分区/非分区)的plsql

1、因前期TABLE的存储TABLESPACE设计不合理,或者需要对某个TABLESPACE进行维护管理,需要将该TABLESPACE中的对象转移,

ORACLE提供了ALTER TABLE TABLE_NAME MOVE TABLESPACE NEW_TABLESPACE(需要有该表空间权限)的支持。

2、在MOVE TABLESPACE过程中需要注意含LOB字段的表不能直接MOVE,以及分区表的MOVE,在MOVE TABLESPACE之后,对应表的

INDEX将会失效,需要重建。

3、为此写了一个PL/SQL程式进行批量MOVE(未经过严格的测试,请勿在生产库上使用,否则后果请自行承担)

PL/SQL如下:

DECLARE

v_sqltext1    VARCHAR2 (1000);

v_sqltext2    VARCHAR2 (1000);

v_sqltext3    VARCHAR2 (1000);

v_sqltext4    VARCHAR2 (1000);

v_sqltext5    VARCHAR2 (1000);

v_sqltext6    VARCHAR2 (1000);

v_sqltext7    VARCHAR2 (1000);

CURSOR tabletype_cur

IS

SELECT *

FROM dba_tables

WHERE owner = 'SCOTT' AND tablespace_name = 'USERS';

v_table_str   tabletype_cur%ROWTYPE;

CURSOR lob_cur (lobtable VARCHAR2)

IS

SELECT *

FROM dba_lobs

WHERE table_name = lobtable;

CURSOR index_cur (idx VARCHAR2)

IS

SELECT index_name

FROM dba_indexes

WHERE table_name = idx;

CURSOR part_index_cur (partidx VARCHAR)

IS

SELECT index_name

FROM dba_indexes

WHERE table_name = partidx

MINUS

SELECT index_name FROM dba_part_indexes;

BEGIN

OPEN tabletype_cur;

LOOP

FETCH tabletype_cur INTO v_table_str;

IF v_table_str.partitioned = 'NO'                               --是否为分区表

THEN

FOR movelob IN lob_cur (v_table_str.table_name)           --是否含有LOB字段

LOOP

v_sqltext1 :=

'ALTER TABLE SCOTT.'

|| movelob.table_name

|| ' MOVE LOB('

|| movelob.column_name

|| ') STORE AS '

|| movelob.segment_name

|| ' (TABLESPACE TEST)';

EXECUTE IMMEDIATE v_sqltext1;

--DBMS_OUTPUT.put_line (v_sqltext1);

END LOOP;

v_sqltext2 :=

'ALTER TABLE SCOTT.'

|| v_table_str.table_name

|| ' MOVE TABLESPACE TEST';

--DBMS_OUTPUT.put_line (v_sqltext2);

EXECUTE IMMEDIATE v_sqltext2;                                 --移动普通表

FOR moveidx IN index_cur (v_table_str.table_name)  --将移动之后表的对应INDEX重建

LOOP

v_sqltext3 :=

'ALTER INDEX SCOTT.'

|| moveidx.index_name

|| ' REBUILD ONLINE TABLESPACE TEST';

EXECUTE IMMEDIATE v_sqltext3;

--DBMS_OUTPUT.put_line (v_sqltext3);

END LOOP;

END IF;

IF v_table_str.partitioned = 'YES'

THEN                          --分区表分区的移动,暂不考虑有子分区的情况,若MOVE子分区将报ORA-14257

FOR part

IN (SELECT partition_name

FROM dba_tab_partitions

WHERE     subpartition_count = 0

AND table_name = v_table_str.table_name)

LOOP

v_sqltext4 :=

'ALTER TABLE SCOTT.'

|| v_table_str.table_name

|| ' MOVE PARTITION '

|| part.partition_name

|| 'TABLESPACE TEST';

EXECUTE IMMEDIATE v_sqltext4;

--DBMS_OUTPUT.put_line (v_sqltext4);

FOR movepartidx1

IN (SELECT index_name

FROM dba_ind_partitions

WHERE     subpartition_count = 0

AND partition_name = part.partition_name)

LOOP

v_sqltext5 :=

'ALTER INDEX '

|| movepartidx1.index_name

|| ' REBUILD PARTITION '

|| part.partition_name

|| ' TABLESPACE TEST';

EXECUTE IMMEDIATE v_sqltext5;              --将移动之后分区表的分区INDEX重建

END LOOP;

END LOOP;

v_sqltext6 :=

'ALTER TABLE SCOTT.'

|| v_table_str.table_name

|| 'MODIFY DEFAULT ATTRIBUTES TABLESPACE TEST';

EXECUTE IMMEDIATE v_sqltext6;

--DBMS_OUTPUT.put_line (v_sqltext6);

FOR movepartidx2 IN part_index_cur (v_table_str.table_name) --将移动之后分区表的全局INDEX重建

LOOP

v_sqltext7 :=

'ALTER INDEX SCOTT.'

|| movepartidx2.index_name

|| ' REBUILD ONLINE TABLESPACE TEST';

EXECUTE IMMEDIATE v_sqltext7;

--DBMS_OUTPUT.put_line (v_sqltext7);

END LOOP;

END IF;

END LOOP;

CLOSE tabletype_cur;

EXCEPTION

WHEN OTHERS

THEN

DBMS_OUTPUT.put_line (SQLERRM);

END;

/

总结:该PL/SQL主要是通过判断一个用户下的表是否为分区表进行move,并根据该表的对象类型来做处理,存在过多的逻辑判断,比较繁琐,

且是根据表类型来进行的,有比较大的局限性,后面考虑从需要move的tablespace方向出发,对tablespace上的对象分类进行move。如:

A)先将该tablespace中的含LOB字段的表move,并重建索引。

B)之后将该tablespace中的分区表进行move,包含分区,子分区,并重建索引,包含全局索引,分区索引,含子分区索引。

C)在之后查看该tablespace中是否有LONG字段的表,有就进行处理。

D) 之后对剩下的普通表进行move,并重建索引,就可将整个tablespace中的对象move。

最后,对于move table的作用和影响请结合shrink table自行查询。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值