9

tablespace reportに属する分割テーブルがあります。代わりにテーブルスペースレコードに移動したい。

1 つの可能性は、テーブルを削除して新しいテーブルスペースに再作成することですが、テーブルには移動後も存続する必要があるデータがあるため、これはオプションではありません。

パーティションが実際に表領域レポートに属していることを確認することから始めました。

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をうまく機能させることができませんでした。

既存のパーティションをすべて新しいテーブルスペースに移動しても、新しいパーティションを作成するときにまだ問題があります。古い表領域レポートでは、新しいパーティションがまだ作成されています。新しいテーブルスペースレコードに新しいパーティションが作成されるように変更するにはどうすればよいですか?

4

6 に答える 6

25

無効化される可能性のあるインデックスも考慮する必要があります-これに加えて、デフォルトのテーブルスペースのリセットに関する質問をカバーするために、これが実装したい完全なプロセスだと思います:

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;
于 2010-01-04T13:52:16.153 に答える
9

PL/SQL を使用するか、SQL を使用してステートメントを生成することができます。単純な SQL を使用して、alter table ステートメントを生成することにしました。

--set linesize
set lines 100

--This Query generates the alter table statements:
SELECT 'ALTER TABLE '
       ||table_name
       ||' MOVE PARTITION '
       ||partition_name
       ||' TABLESPACE REPORT;'
FROM   all_tab_partitions
WHERE  table_name = 'requestLog'; 

前のステートメントからの出力を実行できます。

すべてのユーザーには、デフォルトのテーブルスペースがあります。作成/変更時に他に何も指定されていない場合、新しいデータベース オブジェクトはそのデフォルト テーブルスペースに作成されます。

于 2010-01-04T10:53:01.940 に答える
4

表領域内でデータを移動する最も簡単な方法:

分割されていないすべてのテーブルの移動

SELECT 'ALTER TABLE '||OWNER|| '.'||TABLE_NAME||' MOVE TABLESPACE ARCHIVE;'  
FROM ALL_tables 
where owner = 'owner_name' 
and temporary != 'Y'
and partitioned != 'YES';

分割されたテーブル

SELECT 'ALTER TABLE '|| TABLE_OWNER||'.'||TABLE_NAME||' MOVE PARTITION ' ||  PARTITION_NAME||  ' TABLESPACE ARCHIVE;'  FROM ALL_tab_partitions 
WHERE TABLE_OWNER = 'owner_name' 
AND table_NAME NOT LIKE 'BIN$%';

非パーティション索引

SELECT 'ALTER INDEX '|| OWNER||'.'||OBJECT_NAME ||' REBUILD TABLESPACE ARCHIVE ;' 
FROM ALL_OBJECTS 
WHERE OBJECT_TYPE ='INDEX'
AND OWNER = 'owner_name';

パーティション索引

SELECT  'ALTER INDEX '||I.INDEX_NAME||'REBUILD PARITION'|| S.PARTITION_NAME || ' TABLESPACE  ARCHIVE ' 
                   FROM  DBA_INDEXES I,    DBA_SEGMENTS S
                  WHERE  I.INDEX_NAME = S.SEGMENT_NAME
                    AND I.INDEX_TYPE IN ('NORMAL', 'BITMAP')
                    AND I.OWNER = 'owner_name'; 
于 2011-10-10T14:39:37.443 に答える
1
--MOVING ALL TABLES FROM USER  
BEGIN
  FOR i IN (
    SELECT * FROM ALL_tables where owner = :owner 
      and (tablespace_name is null or tablespace_name != :tbs)
      and temporary != 'Y'
      and partitioned != 'YES'
    ) LOOP
    EXECUTE IMMEDIATE 'ALTER TABLE '  || i.table_name || ' MOVE TABLESPACE ' || :tbs;
  END LOOP; 
END;


--MOVING ALL INDEX

 BEGIN
  FOR i IN (
    SELECT * FROM ALL_tab_partitions 
    WHERE table_owner = :owner and tablespace_name != :tbs
  ) LOOP
    EXECUTE IMMEDIATE 'ALTER TABLE ' 
      || i.table_name || ' MOVE PARTITION '
      || i.partition_name ||' TABLESPACE '|| :tbs;
  END LOOP;
END;


--MOVING ALL PARTATION TABLES FROM USER  

BEGIN
  FOR i IN (
    SELECT * FROM ALL_tables where owner = :owner and partitioned = 'YES'
  ) LOOP
    EXECUTE IMMEDIATE 'ALTER TABLE '
      || i.table_name || ' MODIFY DEFAULT ATTRIBUTES TABLESPACE ' || :tbs;
  END LOOP;
END;
于 2011-06-10T09:54:22.247 に答える
0

これがオプションである場合、最も簡単な方法は、テーブルの名前を変更し ( ALTER TABLE requestLog RENAME TO requestLogTmp;)、正しいテーブルスペースにすべてのインデックスを含む同じテーブルを作成し、古いテーブルからデータをコピーすることです。

INSERT INTO requestLog ( SELECT * FROM requestLogTmp )

すべてが稼働したら、古いテーブルを削除できます。

于 2010-01-04T10:32:28.970 に答える