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

2024-04-01

我有一个属于表空间的分区表report。我想将它移动到表空间record反而。

一种可能性是删除表并在新表空间中重新创建它,但这对我来说不是一个选择,因为表中的数据需要在移动后继续存在。

我首先检查分区是否确实属于表空间报告:

SELECT * FROM user_tab_partitions WHERE table_name = 'REQUESTLOG';

然后我就尝试了:

ALTER TABLE requestLog MOVE TABLESPACE record;

但这给了我错误 ORA-145111“无法对分区对象执行操作”。

然后我发现我可以使用以下方法移动各个分区:

ALTER TABLE requestLog MOVE PARTITION "2009-12-29" TABLESPACE report;

但由于表有 60 个分区(基于日期),并且因为我可能必须对多个系统执行此操作,所以我想循环所有分区名称,将每个分区移动到新的表空间。我尝试过,但无法让 SQL 正常工作。

即使我将所有现有分区移动到新表空间,创建新分区时仍然存在问题。新分区仍然创建在旧表空间中report。如何更改以便在新表空间中创建新分区record?


您还必须考虑可能无效的索引 - 除此之外,为了涵盖有关重置默认表空间的问题,我认为这是您想要实现的完整过程:

1)移动分区(根据 zürigschnäzlets 的答案的 PL/SQL 循环)

这些是我在定义 a_tname、a_destTS、vTname 和 vTspName 的匿名块包装器中使用的过程 - 它们应该为您提供总体思路:

procedure mvTabPart (a_tname in varchar2, a_destTS in varchar2) is
cursor pCur(vTname varchar2, vTspName varchar2) is
  select table_name, partition_name
  from user_tab_partitions
  where table_name = vTname
      and tablespace_name not like vTspName
  order by partition_position desc;
begin
for pRow in pCur(a_tname, a_destTS) loop
 sqlStmnt := 'alter table '||pRow.table_name||
             ' move partition '||pRow.partition_name||
             ' tablespace '||a_destTS;
execute immediate sqlStmnt;
end loop;
end mvTabPart;

2) 设置表默认分区表空间,以便在那里创建新分区:

    procedure setDefTabPart (a_tname in varchar2, a_destTS in varchar2) is
    cursor tCur(vTname varchar2) is
      select table_name
      from user_part_tables
      where table_name = vTname;
    begin
    for tRow in tCur(a_tname) loop
     sqlStmnt := 'alter table '||tRow.table_name||
                 ' modify default attributes '||
                 ' tablespace '||a_destTS;
    execute immediate sqlStmnt;
    end loop;
end setDefNdxPart;

3) 设置索引默认分区表空间,以便在您想要的位置创建新索引分区(如果有):

procedure setDefNdxPart (a_tname in varchar2, a_destTS in varchar2) is
cursor iCur(vTname varchar2) is
  select index_name
  from user_part_indexes
  where index_name in (select index_name
             from user_indexes where table_name = vTname);
begin
for iRow in iCur(a_tname) loop
 sqlStmnt := 'alter index '||iRow.index_name||
             ' modify default attributes '||
             ' tablespace '||a_destTS;
execute immediate sqlStmnt;
end loop;

end setDefNdxPart;

4) 重建任何需要重建且不在所需表空间中的分区索引:

procedure mvNdxPart (a_tname in varchar2, a_destTS in varchar2) is
cursor ndxCur(vTname varchar2, vTspName varchar2) is
select i.index_name index_name, ip.partition_name partition_name
  from user_ind_partitions ip, user_indexes i
  where i.index_name = ip.index_name
     and i.table_name = vTname
     and i.partitioned = 'YES'
     and (ip.tablespace_name not like vTspName or ip.status not like 'USABLE')
  order by index_name, partition_name ;
begin
for ndxRow in ndxCur(a_tname, a_destTS) loop
 sqlStmnt := 'alter index '||ndxRow.index_name||
             ' rebuild partition '||ndxRow.partition_name||
             ' tablespace '||a_destTS;
execute immediate sqlStmnt ;
end loop;
end mvNdxPart;

5) 重建任何全局索引

procedure mvNdx (a_tname in varchar2, a_destTS in varchar2) is
cursor ndxCur(vTname varchar2, vTspName varchar2) is
  select index_name
  from user_indexes
  where table_name = vTname
       and partitioned = 'NO'
       and (tablespace_name not like vTspName or status like 'UNUSABLE')
  order by index_name ;
begin
for ndxRow in ndxCur(a_tname, a_destTS) loop
 sqlStmnt := 'alter index '||ndxRow.index_name||
             ' rebuild tablespace '||a_destTS;
execute immediate sqlStmnt ;
end loop;
end mvNdx;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Oracle 11g 中如何将分区表从一个表空间移动到另一个表空间? 的相关文章

随机推荐