0

我在交换分区时遇到了 ORA-14097。谁能分享我一些光?

我有以下 source_tbl(非分区)表,并打算使用“VALID_PERIOD_END”列对其进行分区

CREATE TABLE source_tbl
   (    INVOICE_ID NUMBER(15,0) NOT NULL ENABLE, 
    LATEST_FLAG_NAME VARCHAR2(3000), 
    STD_HASH **RAW**(1000), 
    VALID_PERIOD_START TIMESTAMP (6), 
    VALID_PERIOD_END **TIMESTAMP** (6), 
    OVERSEAS NUMBER, 
   .. <another 20 number columns)
    VIP_NO NUMBER
   ) partition by range(VALID_PERIOD_END)
nologging;

该表现在有 5M 行,我想按 VALID_PERIOD_END 对其进行分区,这样如果它是“9999-12-31 23:59:59”(当前)将在一个分区中,而其余的将在另一个分区中

我创建了第二个名为 TEMP_tbl 的表

CREATE TABLE TEMP_tbl
   (    INVOICE_ID NUMBER(15,0) NOT NULL ENABLE, 
    LATEST_FLAG_NAME VARCHAR2(3000), 
    STD_HASH **RAW**(1000), 
    VALID_PERIOD_START TIMESTAMP (6), 
    VALID_PERIOD_END **TIMESTAMP** (6), 
    OVERSEAS NUMBER, 
   .. <another 20 number columns)
    VIP_NO NUMBER
   )partition by range(VALID_PERIOD_END)
(partition p1 values less than(maxvalue)) nologging;

TEMP_tbl 具有与 source_tbl 完全相同的数据结构,因为脚本是使用 dbms_metadata.get_ddl驱动的

我已经执行了收集表状态,没有返回任何错误

EXEC DBMS_STATS.gather_table_stats(USER, upper('source_tbl'), cascade => TRUE);

但是,当我尝试执行以下交换分区语句时,出现上述错误

alter table TEMP_tbl
          exchange partition p1
          with table source_tbl
          without validation
          update global indexes
;

我检查了“user_tab_cols”,并确认 source_tbl 中没有隐藏列。会是因为我表中的原始列吗?

提前致谢!

4

1 回答 1

1

Oracle 12.2 引入了两个新的分区特性,这将在此为您提供很大帮助。

  1. 引入了一个新的ALTER TABLE MODIFY PARTITION BYDDL,它允许将非分区表转换为分区表。此操作会将现有非分区表中的数据复制到新表分区中,因此可以长时间运行。您可以指定ONLINE关键字在联机模式下进行操作,这意味着在运行时将允许对表进行 DML 操作ALTER TABLE。例如:
    ALTER TABLE source_tbl
      MODIFY PARTITION BY RANGE(VALID_PERIOD_END)
      (partition p1 values less than (timestamp '9999-12-31 23:59:59'),
       partition p2 values less than (maxvalue))
      ONLINE;
  1. 为了帮助EXCHANGE PARTITION您解决所面临的问题,该FOR EXCHANGE WITH TABLE子句在CREATE TABLE. 这专门用于在创建将与现有表交换的新表时精确匹配物理列。可以选择FOR EXCHANGE WITH TABLE与 一起使用PARTITION BY来创建可以与源表交换的分区表。例如:
    CREATE TABLE TEMP_tbl
      PARTITION BY RANGE(VALID_PERIOD_END)
      (partition p1 values less than(maxvalue))
      FOR EXCHANGE WITH TABLE source_tbl;

这是一篇描述这两种分区增强功能的博客文章。这是另一篇博客文章,专门讨论使用CREATE TABLE ... FOR EXCHANGE WITH TABLE来解决EXCHANGE PARTITION错误。

您没有提及您使用的是哪个版本的 Oracle,因此您可能仍在运行 11g。在这种情况下,您可能需要深入USER_TAB_COLS了解这两个表之间的区别。您提到您已经检查了隐藏列(这很好),但可能会发生其他不匹配。

要记住的一件事是NULLABLE列属性必须在两个表之间匹配。如果一个表具有主键约束而另一个没有,则该列可能在具有主键的表中不可为空,而在另一表中可为空,这将导致 ORA-14097。

如果这不能解释问题,您还可以检查SEGMENT_COLUMN_ID排序、DATA_TYPEDATA_LENGTHDATA_PRECISIONDATA_PRECISION。由于您曾经dbms_metadata.get_ddl创建表,这些东西应该匹配,但必须有一些差异,否则您不会收到错误。

RAW(1000)列不应该是一个问题EXCHANGE PARTITION

于 2021-07-28T22:29:48.140 回答