回答

收藏

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

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

我有一个属于表空间 报告 的分区表。我想将其移至表空间 记录 。1 O% r# b0 H4 n0 W5 e# n) X
一种可能性是删除表并在新表空间中重新创建它,但这对我来说不是一个选择,因为表中有数据需要在移动后幸存。
% H- I! [9 {: h4 _% J我首先使用以下命令检查分区是否真正属于表空间报告:- Q  s( p! B9 |5 j" U
SELECT * FROM user_tab_partitions WHERE table_name = 'REQUESTLOG';' X9 Q$ ?) p: {8 |7 N  l6 q
然后我只是尝试:+ B  l  H" ]3 X7 x* e" p
ALTER TABLE requestLog MOVE TABLESPACE record;
8 q9 w: B& O, \1 V" L但这给了我错误ORA-145111``无法对已分区的对象执行操作’‘。
! z$ k1 q. f+ L然后我发现我可以使用以下方法移动单个分区:( g4 ~/ ~; j. f1 |
ALTER TABLE requestLog MOVE PARTITION "2009-12-29" TABLESPACE report;
2 x& X5 Q" C$ @* A# u* n0 V, ~但是由于该表有60个分区(基于日期),并且由于可能需要对多个系统执行此操作,因此我想遍历所有分区名,并将每个分区名移至新的表空间。我曾尝试过,但无法完全使SQL正常工作。+ r) v* \$ i( Z: ^8 E9 \$ {
即使我将所有现有分区都移动到新表空间,在创建新分区时仍然存在问题。新分区仍在旧表空间 报告中 创建。如何更改以便在新表空间 记录 中创建新分区?! r( L6 Q/ |: n! @
               
; B/ \  N* c$ s. B解决方案:! q2 G3 P0 V$ @2 W
               
7 n! v# V+ U" K5 c
3 \, o* e& ]1 Y9 ?
0 S  [. H" {6 w7 d, S5 ^                您还必须考虑可能使索引无效的索引,以解决有关重置默认表空间的问题,我认为这是您要实现的完整过程:
" i- U* C! j% D& w. J0 c) p1)移动分区(根据zbrrigschn盲zlets的回答进行PL / SQL循环)
- x  n9 d/ z4 X这些是我在定义a_tname,a_destTS,vTname和vTspName的匿名块包装程序中使用的过程-它们应为您提供大致的概念:
2 ?6 I. r8 E. pprocedure mvTabPart (a_tname in varchar2, a_destTS in varchar2) is( A! r4 ^+ N) Q5 E# }, x; z& E& c
cursor pCur(vTname varchar2, vTspName varchar2) is/ l/ K+ u) A1 Q3 _
  select table_name, partition_name
. S$ \" ^3 t! `5 y) J1 p$ u  from user_tab_partitions
* C6 r+ _/ Z+ i" T9 o2 M' x- p  where table_name = vTname. [- s6 j( F1 m4 H: O* G
      and tablespace_name not like vTspName
+ h5 B7 C1 t- e+ K- F% r  f  order by partition_position desc;  c9 P1 M+ f$ ^, ?% |
begin
5 Y9 R  t. G- o5 ^/ a) Lfor pRow in pCur(a_tname, a_destTS) loop( J6 P$ M, a! f5 ^  x; n
sqlStmnt := 'alter table '||pRow.table_name||
& a- P. R; b8 E. K; k3 q8 ~             ' move partition '||pRow.partition_name||" n* h" q" b% ~6 f
             ' tablespace '||a_destTS;7 f: E+ A& E8 h0 z8 l* X) `! b7 I
execute immediate sqlStmnt;
( D$ a9 s: j5 F5 Y2 vend loop;
, }$ D2 G# R% v; L* wend mvTabPart;. K# b" i# n. t( Q% A+ Y0 U
2)设置表默认分区表空间,以便在那里创建新分区:# n" k# f! I: ]5 Y7 f8 I
    procedure setDefTabPart (a_tname in varchar2, a_destTS in varchar2) is
6 S- a/ B* Y8 Z* {! o    cursor tCur(vTname varchar2) is$ V0 w- T# k6 _- \- P" U3 U
      select table_name* s( N8 S  ~, d
      from user_part_tables
  i1 S8 P( C8 E; t      where table_name = vTname;& X. \* P- A; f
    begin/ F) F5 y4 z; x$ n  ?4 c  X; U0 [
    for tRow in tCur(a_tname) loop
( H- X$ I/ D' ^% Z# J+ A     sqlStmnt := 'alter table '||tRow.table_name||
0 S9 I7 f, D, w1 n5 c% x& r                 ' modify default attributes '||
* e1 d! T( |  k  J- c                 ' tablespace '||a_destTS;9 @8 \3 j. m/ U! z9 X
    execute immediate sqlStmnt;
- k" g% G2 h: `& `5 R  A& M    end loop;; f0 j0 t  y+ B0 l( ^6 L/ [+ f
end setDefNdxPart;
" P7 i% G% R3 D3 a$ |" {# t0 K& h% Y3)设置索引默认分区表空间,以便在需要的位置创建新的索引分区(如果有):+ e( z/ a; ~6 w/ I, T- P! H1 J
procedure setDefNdxPart (a_tname in varchar2, a_destTS in varchar2) is9 b  ~' G; y9 Q& X: r  t5 T8 b
cursor iCur(vTname varchar2) is
1 e5 W7 b- v4 }$ G, \  select index_name
1 t8 D/ A$ x! D( d  from user_part_indexes
6 F$ L+ |% z* b% V( Z9 {  where index_name in (select index_name
, v* I2 A+ r, L8 W/ ]. \- t             from user_indexes where table_name = vTname);
/ ^7 B& @6 V: ^6 ?begin
8 u: f3 @& ]/ r' Z0 h8 X6 [9 ffor iRow in iCur(a_tname) loop
/ l5 _& |! _, K% V* L6 Z/ G3 u sqlStmnt := 'alter index '||iRow.index_name||
; U- ~( g; d- B! h& k             ' modify default attributes '||1 w4 [6 \% l1 B$ f* d$ W
             ' tablespace '||a_destTS;
9 s8 E& [0 M9 I3 e, eexecute immediate sqlStmnt;% w# u- n8 Y7 m0 [6 l
end loop;
" s9 t0 c3 u, g, A% ]end setDefNdxPart;- f; v( \  C) E1 m8 ?
4)重建需要重建并且不在所需表空间中的所有分区索引:( f7 K: G% C1 q
procedure mvNdxPart (a_tname in varchar2, a_destTS in varchar2) is4 C! c% e2 A+ e, q& ?
cursor ndxCur(vTname varchar2, vTspName varchar2) is
# p" t) @9 Y* a" Qselect i.index_name index_name, ip.partition_name partition_name
' D2 L5 Q. d/ g  from user_ind_partitions ip, user_indexes i
. Q5 i5 v2 ~/ A6 W4 G/ U2 l  where i.index_name = ip.index_name
! c! R( [" u  p     and i.table_name = vTname3 X$ T9 M+ K, J8 i
     and i.partitioned = 'YES'0 m: Q! e& _5 ~6 p4 J: S9 H' c5 M
     and (ip.tablespace_name not like vTspName or ip.status not like 'USABLE')+ J1 t: u' \5 f( c
  order by index_name, partition_name ;
: |- ~9 `# V. l. D4 N& @4 hbegin6 ]' S. B/ A+ s3 Q
for ndxRow in ndxCur(a_tname, a_destTS) loop) i  b9 T# Z" g# E' F2 W* ^$ n
sqlStmnt := 'alter index '||ndxRow.index_name||
- Q. l3 c. d7 ]8 @3 q- B             ' rebuild partition '||ndxRow.partition_name||
7 {2 V- {9 q* T5 @7 R             ' tablespace '||a_destTS;7 M; V% u" g3 K. L
execute immediate sqlStmnt ;
  n; q7 b8 P" A7 X( ]end loop;$ Q/ D% c$ S  F) P; H9 {8 ?
end mvNdxPart;
$ j9 Z. X6 [4 X- [/ i9 S5)重建任何全局索引$ f1 |6 U: j) }
procedure mvNdx (a_tname in varchar2, a_destTS in varchar2) is
' J) F! i4 q6 {. _$ t0 @3 f5 E2 zcursor ndxCur(vTname varchar2, vTspName varchar2) is8 O% F8 {. s6 x( y  D+ ^+ A
  select index_name
; y5 l/ T  S  {* X) |" i$ ]5 p2 G  from user_indexes+ V0 n, ]( j9 A' v
  where table_name = vTname4 h5 S$ h0 [+ [" V& q8 P0 J
       and partitioned = 'NO'2 m# W# R! N& i1 t2 @; k
       and (tablespace_name not like vTspName or status like 'UNUSABLE')
6 v# k9 J: ^, X, _( S! ?( b; o8 p  order by index_name ;
, u; N+ F8 n. E7 ], n5 x/ kbegin
0 n* c$ q% ~3 ?- sfor ndxRow in ndxCur(a_tname, a_destTS) loop. ~6 n" I: b2 I0 q* a
sqlStmnt := 'alter index '||ndxRow.index_name||
, R' W1 v3 l/ ]  }/ C4 [5 y2 R             ' rebuild tablespace '||a_destTS;
! A$ G5 c) D( G2 M4 U9 V8 \: Vexecute immediate sqlStmnt ;
/ W' K2 p4 |" s7 K$ r2 |end loop;
# G- i4 Y# x: s" t+ lend mvNdx;
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则