メインの親テーブルと、通常のパーティション分割が設定された複数の子テーブルがあり、すべての子テーブルでパーティション列が繰り返されています。参照パーティションに切り替えたい(Oracle 11g)。私の子テーブルには現在2つのパーティションがあり、どちらも削除して参照パーティションに置き換える必要があります。
現在、最後のパーティションを削除し、ALTERコマンドを使用して新しい参照パーティションを追加するという問題に直面しています。
テーブルを削除してデータを失うことができないので、これを行う方法はありますか?パーティション列に作成されたインデックスがあります。
私が使用しているクエリ:
ALTER TABLE CHILD_TABLE_1
DROP PARTITIONS part1, part2
UPDATE INDEXES; --- here only one partition was dropped
ALTER TABLE CHILD_TABLE_1 ADD PARTITION BY REFERENCE (foreign_key_with_parent);
これはエラーになります
エラー:ORA-00902:無効なデータ型SQLState:42000エラーコード:902
パーティション交換を使用するのは、はるかに速く、はるかにクールですが、はるかに複雑な方法です。
私はそれだけを使うでしょう
最小限のテーブル、データ、および列を持つモックアップが与えられた場合:
CREATE TABLE parent(id NUMBER PRIMARY KEY, par NUMBER, c VARCHAR2(30)
) PARTITION BY LIST (par) (
PARTITION p1 VALUES(1,3,5,7,9),
PARTITION p2 VALUES(0,2,4,6,8));
CREATE TABLE child(id REFERENCES parent, par NUMBER, t VARCHAR2(30)
) PARTITION BY LIST (par) (
PARTITION p1 VALUES(1,3,5,7,9),
PARTITION p2 VALUES(0,2,4,6,8));
INSERT INTO parent(id,par,c)
SELECT object_id, mod(object_id,10) as par, object_name FROM all_objects;
INSERT INTO child(id,par,t)
SELECT object_id, mod(object_id,10) as par, object_type FROM all_objects;
最初に、データを保留する保持テーブルを作成します。
CREATE TABLE temp_parent_p1 AS SELECT * FROM parent WHERE 1=0;
CREATE TABLE temp_parent_p2 AS SELECT * FROM parent WHERE 1=0;
CREATE TABLE temp_child_p1 AS SELECT * FROM child WHERE 1=0;
CREATE TABLE temp_child_p2 AS SELECT * FROM child WHERE 1=0;
次に、最初に子、次に親の順にデータを交換します。
ALTER TABLE child EXCHANGE PARTITION p1 WITH TABLE temp_child_p1;
ALTER TABLE child EXCHANGE PARTITION p2 WITH TABLE temp_child_p2;
DROP TABLE child;
ALTER TABLE parent EXCHANGE PARTITION p1 WITH TABLE temp_parent_p1;
ALTER TABLE parent EXCHANGE PARTITION p2 WITH TABLE temp_parent_p2;
DROP TABLE parent;
次に、新しいテーブル構造を再作成します。
CREATE TABLE parent(id NUMBER PRIMARY KEY, par NUMBER, c VARCHAR2(30)
) PARTITION BY LIST (par) (
PARTITION p1 VALUES(1,3,5,7,9),
PARTITION p2 VALUES(0,2,4,6,8));
CREATE TABLE child(id REFERENCES parent, par NUMBER, c VARCHAR2(30)
) PARTITION BY LIST (par) (
PARTITION p1 VALUES(1,3,5,7,9),
PARTITION p2 VALUES(0,2,4,6,8));
次に、パークされたパーティションにインデックスを付ける必要があります。列と制約は、新しいテーブルとまったく同じ構造である必要があります(ただし、名前については心配しないでください)。次に、データを元に戻すことができます。
ALTER TABLE temp_parent_p1 ADD PRIMARY KEY (id);
ALTER TABLE temp_parent_p2 ADD PRIMARY KEY (id);
ALTER TABLE parent EXCHANGE PARTITION p1 WITH TABLE temp_parent_p1;
ALTER TABLE parent EXCHANGE PARTITION p2 WITH TABLE temp_parent_p2;
親が完了したら、子を元に戻すことができます。
ALTER TABLE temp_child_p1 ADD FOREIGN KEY (id) REFERENCES parent(id);
ALTER TABLE temp_child_p2 ADD FOREIGN KEY (id) REFERENCES parent(id);
ALTER TABLE child EXCHANGE PARTITION p1 WITH TABLE temp_child_p1;
ALTER TABLE child EXCHANGE PARTITION p2 WITH TABLE temp_child_p2;
その後のクリーンアップの少し:
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(NULL,'parent');
DBMS_STATS.GATHER_TABLE_STATS(NULL,'child');
END;
/
DROP TABLE temp_parent_p1;
DROP TABLE temp_parent_p2;
DROP TABLE temp_child_p1;
DROP TABLE temp_child_p2;
別のフォーラムで、レンジパーティションからリファレンスへの変換について質問しました。
https://community.Oracle.com/message/14807741
答えは:DBMS_REDEFINITION
新しいテーブルに移行する必要がある余分なスペースと少なくともいくつかの制約(fk)があるので、これは最良のオプションです。
DBMS_REDEFINITION
は、面倒な作業(移動制約)をすべて実行します。
従来のアプローチは