回答

收藏

在Oracle 11g中,如何将分区表从一个表空间移动到另一个表空间?

技术问答 技术问答 418 人阅读 | 0 人回复 | 2023-09-14

我有一个属于表空间 报告 的分区表。我想将其移至表空间 记录 。
9 p" E8 o. d) n8 D3 G一种可能性是删除表并在新表空间中重新创建它,但这对我来说不是一个选择,因为表中有数据需要在移动后幸存。
4 v6 e5 t$ t" D' I+ U9 _我首先使用以下命令检查分区是否真正属于表空间报告:2 o/ R: R$ g, C
SELECT * FROM user_tab_partitions WHERE table_name = 'REQUESTLOG';
3 b: a$ B  @$ B* e0 U- r1 v然后我只是尝试:
! U+ Q! K* N/ pALTER TABLE requestLog MOVE TABLESPACE record;
9 ], G5 U/ n1 b% Y. a- P' I) \$ a/ D但这给了我错误ORA-145111``无法对已分区的对象执行操作’‘。
% C; Y6 |( |$ M2 ]8 ]$ \然后我发现我可以使用以下方法移动单个分区:
2 C  j( D4 E: i/ H7 @% v4 |ALTER TABLE requestLog MOVE PARTITION "2009-12-29" TABLESPACE report;- k2 a# S; f$ t9 U/ o( V
但是由于该表有60个分区(基于日期),并且由于可能需要对多个系统执行此操作,因此我想遍历所有分区名,并将每个分区名移至新的表空间。我曾尝试过,但无法完全使SQL正常工作。
& D2 g! w  Q9 b即使我将所有现有分区都移动到新表空间,在创建新分区时仍然存在问题。新分区仍在旧表空间 报告中 创建。如何更改以便在新表空间 记录 中创建新分区?. u; |# D0 {5 R* H! N
                4 v# _' E! `& O* A; Y; I' m4 c. v/ U
解决方案:- Q9 S/ j( G$ r6 Y8 I1 v8 `
               
  ^5 v# n, n/ U' S5 V1 D5 Q2 d; q7 E6 N+ ]
6 t0 I' q# @7 Q# B3 d3 h. V
                您还必须考虑可能使索引无效的索引,以解决有关重置默认表空间的问题,我认为这是您要实现的完整过程:
( [% X# f  Z$ j+ `0 H3 J1)移动分区(根据zbrrigschn盲zlets的回答进行PL / SQL循环)
! m, W) C9 D& X4 ?这些是我在定义a_tname,a_destTS,vTname和vTspName的匿名块包装程序中使用的过程-它们应为您提供大致的概念:4 z8 }& H2 i( f$ P7 w  q  T, r/ m
procedure mvTabPart (a_tname in varchar2, a_destTS in varchar2) is
" t( F, S9 D" L5 a, C7 ^# \. ]cursor pCur(vTname varchar2, vTspName varchar2) is
& w0 }2 s9 x3 B- I$ Z. w  select table_name, partition_name; q& m! y% x% h& o
  from user_tab_partitions6 Y9 Q9 P3 K2 C8 u! h/ L
  where table_name = vTname4 u5 d$ }4 [9 Y
      and tablespace_name not like vTspName3 @/ U- V# V1 ]0 _# M
  order by partition_position desc;* v  A/ Y0 L/ ^; v0 v: E) }  E* ~
begin! i  q- g8 Q1 w0 }* G5 h
for pRow in pCur(a_tname, a_destTS) loop' }- X- q" y3 ^- K  q' V; d( }
sqlStmnt := 'alter table '||pRow.table_name||
7 l, ?5 Q3 p2 w$ f5 J6 p             ' move partition '||pRow.partition_name||
! G* w- z7 N/ e2 `             ' tablespace '||a_destTS;2 ~# u' W! Q9 n
execute immediate sqlStmnt;2 x& K4 p8 h: J6 R0 y+ I6 y) M4 {3 X
end loop;" O0 L- E' r5 _# V, G) @
end mvTabPart;
- U: W1 s" {3 ~8 K! W. s2)设置表默认分区表空间,以便在那里创建新分区:! Y' J0 E0 z, w$ {( X8 e. Z# A
    procedure setDefTabPart (a_tname in varchar2, a_destTS in varchar2) is
; T1 y4 Z# D* k( a( V& n3 H3 f1 P    cursor tCur(vTname varchar2) is' r; |( ]- D7 E$ \& i3 Z/ T9 h
      select table_name
; O8 Y5 k; J* p      from user_part_tables
! R) C. j- ~% Z, b      where table_name = vTname;" ^8 l. Z$ ~6 o0 g- c' M& ^7 E
    begin( W$ q7 A/ S" c4 l$ J
    for tRow in tCur(a_tname) loop
/ h; z' z: k( ~9 {! A7 O     sqlStmnt := 'alter table '||tRow.table_name||6 p& h  G5 r5 S6 w9 z  B. F
                 ' modify default attributes '||5 H: K3 S0 ~. G, j
                 ' tablespace '||a_destTS;
+ ^; _: I- J, z' i    execute immediate sqlStmnt;
# |( I" H- r. |    end loop;- |3 c, {: l/ a
end setDefNdxPart;
* Q* g' }1 C; c7 h' V" g9 S3)设置索引默认分区表空间,以便在需要的位置创建新的索引分区(如果有):
/ |) U% b$ a  H/ h, w3 T; Hprocedure setDefNdxPart (a_tname in varchar2, a_destTS in varchar2) is* m) i5 ~# H$ `: \, t1 T
cursor iCur(vTname varchar2) is
; z( ^' L. R* C$ u( {  select index_name
  f' i7 }6 |6 Z+ g) q5 W  from user_part_indexes
( B" s0 B1 }  v% J4 }; T  where index_name in (select index_name
2 q6 |' S% s7 X9 V. S) I             from user_indexes where table_name = vTname);
  K' W  x  V* h; K$ F- h! r& m  Dbegin
1 L1 ]. ?6 E3 L8 W1 V+ cfor iRow in iCur(a_tname) loop
  k. B, d/ f' }! B% J sqlStmnt := 'alter index '||iRow.index_name||2 r1 I+ R$ h3 i/ J/ R' U- C
             ' modify default attributes '||" l! z& W5 P6 F6 P5 y
             ' tablespace '||a_destTS;
! s" t! |2 _( V9 s% mexecute immediate sqlStmnt;1 f$ b9 x( z$ B* Y  C( w3 h. Y
end loop;
+ Y/ m; a$ v7 Y& H+ Qend setDefNdxPart;
$ r/ i6 {( ?" w% u$ Y# N& H4)重建需要重建并且不在所需表空间中的所有分区索引:
! {5 S8 k6 s, d$ I3 Oprocedure mvNdxPart (a_tname in varchar2, a_destTS in varchar2) is
5 b, m; J; T' g/ b1 Wcursor ndxCur(vTname varchar2, vTspName varchar2) is
/ ]' m7 f0 V' _+ k: A3 n2 m- ?9 xselect i.index_name index_name, ip.partition_name partition_name; L  L5 A# ^7 Z% R; U5 u! n
  from user_ind_partitions ip, user_indexes i0 v  `( U: M$ c- ~& X3 o
  where i.index_name = ip.index_name
! y5 l* H1 r+ H+ e8 A# P     and i.table_name = vTname
' v# L+ J; i6 s5 _: l3 P     and i.partitioned = 'YES'8 K2 ~0 u# C5 F2 x
     and (ip.tablespace_name not like vTspName or ip.status not like 'USABLE')3 ?9 `* |$ U0 B$ H+ Z4 H8 v  ]
  order by index_name, partition_name ;! ?7 N0 ~" a( L
begin
; I+ u' @  i# ~. E6 J8 Nfor ndxRow in ndxCur(a_tname, a_destTS) loop
$ n7 @( U$ t, {. e' j sqlStmnt := 'alter index '||ndxRow.index_name||
( p. F8 H  c  {- @             ' rebuild partition '||ndxRow.partition_name||) z; g8 y  ~/ }4 e. J( Z# k
             ' tablespace '||a_destTS;* G  a' m& P- @) P; `5 G
execute immediate sqlStmnt ;1 U0 a7 [! A3 n2 A; a% F
end loop;, q2 u/ D$ Z) P/ d& ?; h
end mvNdxPart;0 S& h4 \: q5 c: N
5)重建任何全局索引
, X3 S: J3 t% P3 B8 Z3 ?  \" sprocedure mvNdx (a_tname in varchar2, a_destTS in varchar2) is
* v4 |) `$ m) v. N( Jcursor ndxCur(vTname varchar2, vTspName varchar2) is. A& |. \& Q+ C, L
  select index_name0 M* s, d+ M6 r
  from user_indexes
5 K. \- v& z& X2 B. |  where table_name = vTname
% Q* j( C: Y! {6 I! ?: _3 K& [       and partitioned = 'NO'& x9 g! k9 l4 m/ \2 x" [1 ^
       and (tablespace_name not like vTspName or status like 'UNUSABLE')$ M7 \9 ?+ P1 V2 d" {
  order by index_name ;
. ^! m' ^3 Z% A' h7 n" I/ \$ Lbegin
! f8 Y6 h( d( D( F4 N( ]( Jfor ndxRow in ndxCur(a_tname, a_destTS) loop0 B. I& e0 K( f2 ~9 }5 k
sqlStmnt := 'alter index '||ndxRow.index_name||4 J6 M/ C/ c9 e' [
             ' rebuild tablespace '||a_destTS;
! ?+ X# `& w. c2 }, gexecute immediate sqlStmnt ;
( ~0 X' G# ?2 \* ?! o3 [end loop;
7 O6 O7 a( t2 wend mvNdx;
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则