Du kan ikke partitionere en eksisterende tabel på den måde. Denne erklæring ændrer den partition, der ikke er blevet oprettet endnu. Jeg kender ikke den automatiske måde at udføre denne operation på, og jeg er ikke sikker på, at du kan gøre det.
Selvom jeg har gjort dette mange gange, men med manuelle trin. Gør følgende, hvis du ikke kan finde en automatiseret løsning:
- Opret en opdelt tabel med navnet tabelnavn_del med dine klausuler og alle dine præferencer.
- Indsæt alle rækker fra den oprindelige tabel i denne opdelte tabel. Vær opmærksom på kompression. Hvis du har en vis komprimering på tabellen (Basic eller HCC), skal du bruge + APPEND tip.
- Opret på en partitioneret tabel dine begrænsninger og indekser fra den originale tabel.
- Omdøb tabellerne, og slip den oprindelige tabel. Tab det ikke, før du regner med dem.
Jeg så, at din tabel har mulighed for automatisk at oprette partition, hvis den ikke eksisterer. (NUMTOYMINTERVAL(1,'MÅNED')) Så du skal oprette din tabel med kun den første partition. Jeg går ud fra, at du her har en masse skrivebeskyttet data, så du vil ikke have noget problem med konsistensen i stedet for sidste måned. Sandsynligvis er der nogle læse-skrive data, så der skal du være mere forsigtig med det øjeblik, hvor du vil indsætte data i en ny tabel og skifte tabel.
Håber at hjælpe dig. Så vidt jeg ved, kan der være en pakke ved navn DBMS_REDEFINITION, der kan hjælpe dig med en automatiseret version af mine trin. Hvis du har brug for flere detaljer eller har brug for hjælp til min metode, så tøv ikke med.
OPDATERING: Fra Oracle 12c R2 kan du konvertere en tabel fra en upartitioneret til en opdelt tabel med din metode. Find et link nedenfor. Nu er dette en udfordring for mig, og jeg prøver at konvertere, men jeg tror, der ikke er nogen måde at lave denne konvertering online i 12c R1.
Løsning
Jeg har fundet en løsning til dig. Her vil du have alle mine trin, som jeg kører for at konvertere bord 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');
I slutningen af scriptet vil du se, at den originale tabel er partitioneret.