回答

收藏

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

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

我有一个属于表空间 报告 的分区表。我想将其移至表空间 记录 。
# g; p  E2 g/ Y9 y/ F6 ~& z一种可能性是删除表并在新表空间中重新创建它,但这对我来说不是一个选择,因为表中有数据需要在移动后幸存。
% N. B" s  {% R# @2 [8 `, r( B我首先使用以下命令检查分区是否真正属于表空间报告:) `0 J' I- N* \$ A# b) ^
SELECT * FROM user_tab_partitions WHERE table_name = 'REQUESTLOG';
8 X  q; ^. Y( |3 L2 N5 v. c然后我只是尝试:
( E# H' m$ ^; A, u# ~/ _' BALTER TABLE requestLog MOVE TABLESPACE record;0 `" ^# [9 @& p0 K) w! Z
但这给了我错误ORA-145111``无法对已分区的对象执行操作’‘。
0 T6 |, M8 _2 k( Q5 n然后我发现我可以使用以下方法移动单个分区:9 b# u' Q0 F; U
ALTER TABLE requestLog MOVE PARTITION "2009-12-29" TABLESPACE report;
/ S4 _$ @8 D2 p但是由于该表有60个分区(基于日期),并且由于可能需要对多个系统执行此操作,因此我想遍历所有分区名,并将每个分区名移至新的表空间。我曾尝试过,但无法完全使SQL正常工作。
: [: V% p! B, y5 q+ H& t1 W+ u9 q% |即使我将所有现有分区都移动到新表空间,在创建新分区时仍然存在问题。新分区仍在旧表空间 报告中 创建。如何更改以便在新表空间 记录 中创建新分区?2 ^7 b' c' L1 c1 L, |
                . x" n- E4 T6 O0 z8 R
解决方案:( S+ `$ V- |3 k5 R) ]8 P+ p) a3 X
               
9 U9 O5 {: A- _! k+ g3 r3 I- k3 d' z, d9 t% I
- t$ h' X3 L7 T9 d
                您还必须考虑可能使索引无效的索引,以解决有关重置默认表空间的问题,我认为这是您要实现的完整过程:: X, i3 A7 w. }2 N/ U: N
1)移动分区(根据zbrrigschn盲zlets的回答进行PL / SQL循环)) Y, v% g. L$ B0 @
这些是我在定义a_tname,a_destTS,vTname和vTspName的匿名块包装程序中使用的过程-它们应为您提供大致的概念:
' A# A4 ^8 j% ?. U1 O4 qprocedure mvTabPart (a_tname in varchar2, a_destTS in varchar2) is
7 h% |% P2 P2 o% T# V& p7 e7 Ccursor pCur(vTname varchar2, vTspName varchar2) is6 ^7 S' y5 H, w) u% N
  select table_name, partition_name
$ K2 |5 t9 o! y6 N- z1 f' U+ Y  from user_tab_partitions
1 \, M& v! O" U' C' }  where table_name = vTname
8 }. H6 h8 H7 }& g' ~& ~      and tablespace_name not like vTspName
. l8 Q- w, Z5 E( p  order by partition_position desc;
, M2 J. r3 H2 P4 B' Ubegin1 b! K# e, j/ q6 Y
for pRow in pCur(a_tname, a_destTS) loop
# _" v: h& D' }" X9 ^( X' F# i sqlStmnt := 'alter table '||pRow.table_name||
" t7 t' {# V/ F6 h" V$ E             ' move partition '||pRow.partition_name||9 V9 ]" Q+ [4 p  r8 l; h# @# M
             ' tablespace '||a_destTS;
+ ?* }8 Z1 i/ ]. t' t1 w  j% b! Dexecute immediate sqlStmnt;
1 D/ Y$ l) ?' z' k; F6 n5 p5 lend loop;
1 U9 P, E, E8 m4 D% P4 ]: Aend mvTabPart;
( {! Q7 z7 Z' Z2)设置表默认分区表空间,以便在那里创建新分区:
) w: ]! b" U; ~1 V    procedure setDefTabPart (a_tname in varchar2, a_destTS in varchar2) is
0 ?; @$ C4 M# O4 U0 G+ g* e0 S    cursor tCur(vTname varchar2) is" I2 a, F. {5 ~3 }  c$ O4 I6 H! R! J7 [
      select table_name
9 |4 `. y3 Y+ z* m$ o      from user_part_tables
7 G/ T* H" _) f1 U1 t* z# s      where table_name = vTname;
. f% B7 J7 p4 J/ s  z" z! }) K    begin
" f/ _- S3 v+ H1 n; [, m    for tRow in tCur(a_tname) loop
, g" p4 `+ G* l. H# f) N     sqlStmnt := 'alter table '||tRow.table_name||
) [% C$ O) d, J3 D                 ' modify default attributes '||' _/ b0 X7 G/ a1 d! X
                 ' tablespace '||a_destTS;1 }3 C4 ~) K( ~2 W8 @4 E' V* R! p6 }9 Q
    execute immediate sqlStmnt;2 i/ A& y2 x6 M) Q
    end loop;
1 A; n, x: g. }* V3 Xend setDefNdxPart;- f0 e  ~) e) j
3)设置索引默认分区表空间,以便在需要的位置创建新的索引分区(如果有):; ?% f7 W& b9 Y# R1 X
procedure setDefNdxPart (a_tname in varchar2, a_destTS in varchar2) is# O+ F- S7 f4 D
cursor iCur(vTname varchar2) is
2 X3 y3 o( d' u1 L: r: B6 N+ Q  select index_name+ d3 `  Q- f  i, i5 Z$ ~
  from user_part_indexes  b6 C. t5 E: ~; k! q
  where index_name in (select index_name8 t: @4 D* s' Q3 a
             from user_indexes where table_name = vTname);/ ?! u- e% n, _1 t4 g! ^' Z
begin
! f0 B% |4 t' p& L$ f. x& R" dfor iRow in iCur(a_tname) loop
" W! ^" I2 B7 S sqlStmnt := 'alter index '||iRow.index_name||
4 ^; W+ S8 `2 v, Z4 I' A( c             ' modify default attributes '||
$ M" _% U  u1 T5 E  i1 _. ^             ' tablespace '||a_destTS;
/ l7 \( A! F! {' C9 Bexecute immediate sqlStmnt;7 f2 \! I) u8 A5 f
end loop;
2 g; Y3 Y7 g; t0 tend setDefNdxPart;
. w# L" ?# ]+ w/ h% x2 W4)重建需要重建并且不在所需表空间中的所有分区索引:2 n/ f: [- X/ i6 I- Z3 s
procedure mvNdxPart (a_tname in varchar2, a_destTS in varchar2) is
3 [7 @8 f$ e$ `! E7 Ycursor ndxCur(vTname varchar2, vTspName varchar2) is
  G/ R( N0 E7 f, r  Gselect i.index_name index_name, ip.partition_name partition_name
3 [) h9 n. F9 O2 u( a  from user_ind_partitions ip, user_indexes i
8 r  v4 N; ^2 x8 f4 D2 B  where i.index_name = ip.index_name
6 S$ }# r/ t$ {# A7 X' E     and i.table_name = vTname
. \: U8 I1 t9 ]1 {2 A: [- w     and i.partitioned = 'YES'! @1 a6 n$ ]. R9 o( ?
     and (ip.tablespace_name not like vTspName or ip.status not like 'USABLE')$ [! O9 p( |- {" i' W
  order by index_name, partition_name ;
+ |/ D, m- a; [2 j) d- \, P! ~# }begin
/ a' J, R) ?2 }2 [+ M- ifor ndxRow in ndxCur(a_tname, a_destTS) loop+ v  Q6 q/ l# n
sqlStmnt := 'alter index '||ndxRow.index_name||7 a  n6 |! ?0 S+ v7 p: f3 I0 T
             ' rebuild partition '||ndxRow.partition_name||+ i( M/ a4 `4 L  y% u
             ' tablespace '||a_destTS;
2 c, a3 b9 y* B2 w, f; dexecute immediate sqlStmnt ;
  j% E  y8 U7 Q7 w! Nend loop;
0 B3 E; e5 x0 Q# _1 b8 i* Wend mvNdxPart;/ Y. o0 ?8 m) C' S# z' r
5)重建任何全局索引
0 M9 ^/ f% `" X/ @procedure mvNdx (a_tname in varchar2, a_destTS in varchar2) is& o1 f7 q$ _) G' T7 p$ z
cursor ndxCur(vTname varchar2, vTspName varchar2) is3 n3 t% Z2 b! z3 X# N$ E
  select index_name! U, C) M$ y& Y6 P+ a
  from user_indexes
* g; e: `. u8 J5 c8 t4 X* T  where table_name = vTname1 \2 `6 h- B" k, F
       and partitioned = 'NO'
0 X) i6 f! f: I9 U$ ]' ^& y: `       and (tablespace_name not like vTspName or status like 'UNUSABLE')
$ c( Z" ?) h/ g9 D8 }  G( x  order by index_name ;
. z6 h- ?8 k* k! Sbegin3 q" l3 H* M( U- m( c6 C, C: a
for ndxRow in ndxCur(a_tname, a_destTS) loop
; z4 a! f( c/ X" V sqlStmnt := 'alter index '||ndxRow.index_name||
+ ]6 t! w4 M+ r4 k7 I- a             ' rebuild tablespace '||a_destTS;3 i/ H' d/ R6 V8 Q8 D
execute immediate sqlStmnt ;1 |$ l/ u  m5 x8 _
end loop;
* L( R: @, o- Eend mvNdx;
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则