Oracle
 sql >> Database >  >> RDS >> Oracle

Errore SQL:ORA-14006:nome partizione non valido

Non puoi partizionare una tabella esistente in questo modo. Tale istruzione sta modificando la partizione che non è stata ancora creata. Non conosco il modo automatico per fare questa operazione e non sono sicuro che tu possa farlo.

Anche se ho fatto questa cosa molte volte ma con passaggi manuali. Se non riesci a trovare una soluzione automatizzata, procedi come segue:

  1. Crea una tabella partizionata denominata table_name_part con le tue clausole e tutte le tue preferenze.
  2. Inserisci in questa tabella partizionata tutte le righe della tabella originale. Prestare attenzione alla compressione. Se hai qualche compressione sulla tabella (Base o HCC) devi usare + APPEND suggerimento.
  3. Crea su una tabella partizionata i tuoi vincoli e indici dalla tabella originale.
  4. Rinomina le tabelle e rilascia la tabella originale. Non lasciarlo cadere finché non hai fatto un po' di conti su di loro.

Ho visto che la tua tabella ha la possibilità di creare automaticamente la partizione se non esiste. (NUMTOYMINTERVAL(1,'MONTH')) Quindi devi creare la tua tabella solo con la prima partizione. Presumo che tu abbia qui molti dati di sola lettura, quindi non avrai alcun problema con la coerenza invece del mese scorso. Probabilmente ci sono alcuni dati di lettura-scrittura, quindi devi stare più attento al momento in cui vuoi inserire i dati in una nuova tabella e cambiare tabella.

Spero di aiutarti. Per quanto ne so, potrebbe esserci un pacchetto chiamato DBMS_REDEFINITION che può aiutarti con una versione automatizzata dei miei passaggi. Se hai bisogno di maggiori dettagli o hai bisogno di aiuto sul mio metodo, non esitare.

AGGIORNAMENTO: Da Oracle 12c R2 puoi convertire una tabella da una non partizionata a una partizionata con il tuo metodo. Trova un link qui sotto. Ora questa è una sfida per me e sto cercando di convertire, ma penso che non ci sia modo di effettuare questa conversione online in 12c R1.

https://oracle-base.com/articles/12c/online-conversion-of-a-non-partitioned-table-to-a-partitioned-table-12cr2

Soluzione

Ho trovato una soluzione per te. Qui avrai tutti i miei passaggi che eseguo per convertire la tabella 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');

Alla fine dello script vedrai che la tabella originale è partizionata.