Nie możesz podzielić istniejącej tabeli w ten sposób. Ta instrukcja modyfikuje partycję, która nie została jeszcze utworzona. Nie znam automatycznego sposobu wykonania tej operacji i nie jestem pewien, czy możesz to zrobić.
Chociaż robiłem to wiele razy, ale z ręcznymi krokami. Jeśli nie możesz znaleźć automatycznego rozwiązania, wykonaj następujące czynności:
- Utwórz podzieloną na partycje tabelę o nazwie table_name_part ze swoimi klauzulami i wszystkimi preferencjami.
- Wstaw do tej podzielonej na partycje tabeli wszystkie wiersze z oryginalnej tabeli. Zwróć uwagę na kompresję. Jeśli masz jakąś kompresję na stole (Basic lub HCC), musisz użyć + APPEND wskazówka.
- Utwórz na partycjonowanej tabeli swoje ograniczenia i indeksy z oryginalnej tabeli.
- Zmień nazwy tabel i usuń oryginalną tabelę. Nie upuszczaj go, dopóki nie zaczniesz na nich liczyć.
Widziałem, że twoja tabela ma opcję automatycznego tworzenia partycji, jeśli nie istnieje. (NUMTOYMINTERVAL(1,'MONTH')) Musisz więc utworzyć tabelę tylko z pierwszą partycją. Zakładam, że masz tutaj dużo danych tylko do odczytu, więc nie będziesz miał problemu ze spójnością zamiast zeszłego miesiąca. Prawdopodobnie są jakieś dane do odczytu i zapisu, więc musisz uważać na moment, w którym chcesz wstawić dane do nowej tabeli i zmienić tabele.
Mam nadzieję, że ci pomogę. O ile wiem, może istnieć pakiet o nazwie DBMS_REDEFINITION, który może pomóc w zautomatyzowanej wersji moich kroków. Jeśli potrzebujesz więcej szczegółów lub potrzebujesz pomocy w mojej metodzie, nie wahaj się.
AKTUALIZACJA: Z Oracle 12c R2 możesz przekonwertować tabelę z niepartycjonowanej na partycjonowaną za pomocą swojej metody. Znajdź link poniżej. Teraz jest to dla mnie wyzwanie i próbuję dokonać konwersji, ale myślę, że nie ma sposobu, aby dokonać tej konwersji online w 12c R1.
Rozwiązanie
Znalazłem dla Ciebie rozwiązanie. Tutaj znajdziesz wszystkie moje kroki, które uruchamiam, aby przekonwertować tabelę online. :)
1. Create regular table and populate it.
CREATE TABLE SCOTT.tab_unpartitioned
(
id NUMBER,
description VARCHAR2 ( 50 ),
created_date DATE
);
INSERT INTO tab_unpartitioned
SELECT LEVEL,
'Description for ' || LEVEL,
ADD_MONTHS ( TO_DATE ( '01-JAN-2017', 'DD-MON-YYYY' ),
-TRUNC ( DBMS_RANDOM.VALUE ( 1, 4 ) - 1 ) * 12 )
FROM DUAL
CONNECT BY LEVEL <= 10000;
COMMIT;
2. Create partitioned table with same structure.
--If you are on 11g create table with CREATE TABLE command but with different name. ex: tab_partitioned
CREATE TABLE SCOTT.tab_partitioned
(
id NUMBER,
description VARCHAR2 ( 50 ),
created_date DATE
)
PARTITION BY RANGE (created_date)
INTERVAL( NUMTOYMINTERVAL(1,'YEAR'))
(PARTITION part_2015 VALUES LESS THAN (TO_DATE ( '01-JAN-2016', 'DD-MON-YYYY' )),
PARTITION part_2016 VALUES LESS THAN (TO_DATE ( '01-JAN-2017', 'DD-MON-YYYY' )),
PARTITION part_2017 VALUES LESS THAN (TO_DATE ( '01-JAN-2018', 'DD-MON-YYYY' )));
--this is an alter command that works only in 12c.
ALTER TABLE tab_partitioned
MODIFY
PARTITION BY RANGE (created_date)
(PARTITION part_2015 VALUES LESS THAN (TO_DATE ( '01-JAN-2016', 'DD-MON-YYYY' )),
PARTITION part_2016 VALUES LESS THAN (TO_DATE ( '01-JAN-2017', 'DD-MON-YYYY' )),
PARTITION part_2017 VALUES LESS THAN (TO_DATE ( '01-JAN-2018', 'DD-MON-YYYY' )));
3. Check if the table can be converted. This procedure should run without any error.
Prerequisites: table should have an UNIQUE INDEX and a Primary Key constraint.
EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE('SCOTT','TAB_UNPARTITIONED');
4. Run the following steps like I have done.
EXEC DBMS_REDEFINITION.START_REDEF_TABLE('SCOTT','TAB_UNPARTITIONED','TAB_PARTITIONED');
var num_errors varchar2(2000);
EXEC DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('SCOTT','TAB_UNPARTITIONED','TAB_PARTITIONED', 1,TRUE,TRUE,TRUE,FALSE,:NUM_ERRORS,FALSE);
SQL> PRINT NUM_ERRORS -- Should return 0
EXEC DBMS_REDEFINITION.SYNC_INTERIM_TABLE('SCOTT','TAB_UNPARTITIONED','TAB_PARTITIONED');
EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE('SCOTT','TAB_UNPARTITIONED','TAB_PARTITIONED');
Na końcu skryptu zobaczysz, że oryginalna tabela jest podzielona na partycje.