Takto nemůžete rozdělit existující tabulku. Tento příkaz upravuje oddíl, který ještě nebyl vytvořen. Neznám automatický způsob, jak tuto operaci provést, a nejsem si jistý, zda to dokážete.
I když jsem to udělal mnohokrát, ale pomocí ručních kroků. Pokud nemůžete najít automatické řešení, proveďte následující:
- Vytvořte rozdělenou tabulku s názvem table_name_part s vašimi klauzulemi a všemi vašimi preferencemi.
- Vložte do této rozdělené tabulky všechny řádky z původní tabulky. Pozor na kompresi. Pokud máte v tabulce nějakou kompresi (základní nebo HCC), musíte použít + APPEND nápověda.
- V dělené tabulce vytvořte svá omezení a indexy z původní tabulky.
- Přejmenujte tabulky a zrušte původní tabulku. Nepouštějte to, dokud s nimi nebudete trochu počítat.
Viděl jsem, že vaše tabulka má možnost automatického vytvoření oddílu, pokud neexistuje. (NUMTOYMINTERVAL(1,'MONTH')) Takže musíte vytvořit tabulku pouze s prvním oddílem. Předpokládám, že zde máte spoustu dat pouze pro čtení, takže s konzistencí místo minulého měsíce nebudete mít problém. Pravděpodobně existují nějaká data pro čtení a zápis, takže tam musíte být opatrnější v okamžiku, kdy chcete vkládat data do nové tabulky a přepínat tabulky.
Doufám, že vám pomůžu. Pokud vím, může existovat balíček s názvem DBMS_REDEFINITION, který vám může pomoci s automatizovanou verzí mých kroků. Pokud potřebujete více podrobností nebo potřebujete pomoc s mou metodou, neváhejte.
AKTUALIZACE: Z Oracle 12c R2 můžete pomocí vaší metody převést tabulku z nerozdělené na rozdělenou. Níže najdete odkaz. Nyní je to pro mě výzva a snažím se konvertovat, ale myslím, že neexistuje způsob, jak tuto konverzi provést online v 12c R1.
Řešení
Našel jsem pro vás řešení. Zde budete mít všechny mé kroky, které spouštím k online převodu tabulky. :)
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 konci skriptu uvidíte, že původní tabulka je rozdělena.