ORA-14097: ALTER TABLE EXCHANGE PARTITION 中的列类型或大小不匹配

问题描述

我在交换分区时遇到了 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,.. <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

我已经执行了gather table status,没有返回任何错误

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 中没有隐藏列。是因为我的表中的原始列吗?

提前致谢!

解决方法

Oracle 12.2 引入了两个新的分区特性,它们将帮助您

  1. 引入了新的 ALTER TABLE MODIFY PARTITION BY DDL,允许将非分区表转换为分区表。此操作会将现有未分区表中的数据复制到新表分区中,因此可以长时间运行。您可以指定ONLINE关键字在在线模式下进行操作,这意味着在ALTER TABLE运行时将允许对表进行DML操作。例如:
    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;

Here is a blog article 描述了这两种分区增强功能。还有 here is another blog article 专门讨论使用 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 应该没有问题。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...