SQL错误:ORA-14006:无效的分区名称

Taj*_*der 2 oracle partitioning database-partitioning partition

我正在尝试使用下面的SQL语句对Oracle 12C R1中的现有表进行分区.

ALTER TABLE TABLE_NAME MODIFY
PARTITION BY RANGE (DATE_COLUMN_NAME)
INTERVAL (NUMTOYMINTERVAL(1,'MONTH'))
(
PARTITION part_01  VALUES LESS THAN (TO_DATE('01-SEP-2017', 'DD-MON-RRRR'))
) ONLINE;
Run Code Online (Sandbox Code Playgroud)

得到错误:

Error report -
SQL Error: ORA-14006: invalid partition name
14006. 00000 -  "invalid partition name"
*Cause:    a partition name of the form <identifier> is
           expected but not present.
*Action:   enter an appropriate partition name.
Run Code Online (Sandbox Code Playgroud)

分区需要在data datatype列的基础上进行,间隔为一个月.

表中日期时间列的最小值为01-SEP-2017.

adi*_*e91 8

您不能像这样对现有表进行分区.该语句正在修改尚未创建的分区.我不知道自动执行此操作的方法,我不确定您是否可以执行此操作.

虽然我已经多次做过这件事,但手动步骤.如果找不到自动解决方案,请执行以下操作:

  1. 使用您的子句和所有首选项创建名为table_name_part的分区表.
  2. 从原始表中插入此分区表中的所有行.注意压缩.如果您在桌面上有一些压缩(基本或HCC),则必须使用+ APPEND提示.
  3. 在分区表上创建原始表中的约束和索引.
  4. 重命名表并删除原始表.在你对它们进行一些计数之前不要放弃它.

我看到你的表可以选择自动创建分区,如果它不存在.(NUMTOYMINTERVAL(1,'MONTH'))因此,您必须仅使用第一个分区创建表.我假设你有很多只读数据,所以你不会有任何一致性问题,而不是上个月.可能存在一些读写数据,因此您需要在要在新表和切换表中插入数据时更加小心.

希望能帮到你.据我所知,可能有一个名为DBMS_REDEFINITION的软件包可以帮助您完成我的步骤的自动化版本.如果您需要更多详细信息或需要我的方法帮助,请不要犹豫.

更新: 从Oracle 12c R2,您可以使用您的方法将表从未分区转换为分区表.找到以下链接.现在这对我来说是一个挑战,我正在尝试转换,但我认为没有办法在12c R1中进行在线转换.

在以前的版本中,您可以使用"几乎在线"方式使用EXCHANGE PARTITION或DBMS_REDEFINITION对非分区表进行分区,但这两种方法都需要多个步骤.Oracle Database 12c第2版使得将非分区表转换为分区表变得前所未有的简单,只需要一个命令而且不需要停机.

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

我为你找到了解决方案.在这里,您将完成我在线转换表格所需的所有步骤.:)

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'); 
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');
Run Code Online (Sandbox Code Playgroud)

在脚本的末尾,您将看到原始表已分区.

分区表