sql >> Database >  >> RDS >> Oracle

SQL-fout:ORA-14006:ongeldige partitienaam

Je kunt een bestaande tabel niet zo partitioneren. Die instructie wijzigt de partitie die nog niet is gemaakt. Ik ken de automatische manier om deze bewerking uit te voeren niet en ik weet niet zeker of u dit kunt doen.

Hoewel ik dit vaak heb gedaan, maar met handmatige stappen. Doe het volgende als u geen geautomatiseerde oplossing kunt vinden:

  1. Maak een gepartitioneerde tabel met de naam table_name_part met uw clausules en al uw voorkeuren.
  2. Voeg in deze gepartitioneerde tabel alle rijen van de originele tabel in. Let op compressie. Als je wat compressie op tafel hebt (Basic of HCC), moet je + APPEND gebruiken hint.
  3. Maak op een gepartitioneerde tabel uw beperkingen en indexen van de originele tabel.
  4. Hernoem de tabellen en verwijder de originele tabel. Laat het niet vallen totdat je er wat op hebt berekend.

Ik zag dat uw tabel de optie heeft om automatisch een partitie aan te maken als deze niet bestaat. (NUMTOYMINTERVAL(1,'MONTH')) U hoeft uw tabel dus alleen met de eerste partitie aan te maken. Ik neem aan dat je hier veel alleen-lezen gegevens hebt, dus je zult geen probleem hebben met consistentie in plaats van vorige maand. Waarschijnlijk zijn er lees-schrijfgegevens, dus daar moet je voorzichtiger zijn met het moment waarop je gegevens in een nieuwe tabel wilt invoegen en van tabel wilt wisselen.

Hoop je te helpen. Voor zover ik weet is er misschien een pakket met de naam DBMS_REDEFINITION dat je kan helpen met een geautomatiseerde versie van mijn stappen. Als je meer details nodig hebt of hulp nodig hebt bij mijn methode, aarzel dan niet.

UPDATE: Vanuit Oracle 12c R2 kunt u met uw methode een tabel converteren van een niet-gepartitioneerde naar een gepartitioneerde. Vind hieronder een link. Dit is een uitdaging voor mij en ik probeer te converteren, maar ik denk dat er geen manier is om deze conversie online te maken in 12c R1.

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

Oplossing

Ik heb een oplossing voor je gevonden. Hier vindt u al mijn stappen die ik uitvoer om de tabel online te converteren. :)

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');

Aan het einde van het script zul je zien dat de originele tabel is gepartitioneerd.



  1. De stille modus inschakelen voor Postgres-opdrachten op Heroku

  2. mysql-achtige zoekopdracht getallen uitsluiten

  3. De beste manier om een ​​datadictionary te doorzoeken in sql

  4. Oracle verbinden met SQL Server vanuit Windows