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

ORA-14097: column type or size mismatch in ALTER TABLE EXCHANGE PARTITION

我 运行 在交换分区时进入 ORA-14097。任何人都可以分享我一些光吗?

我有以下 source_tbl(未分区)table 并打算使用“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;

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

我创建了第二个 table,名为 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

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

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

但是,当我尝试执行下面的exchange partition语句时,出现了上面的错误

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

我检查了“user_tab_cols”并确认 source_tbl 中没有隐藏列。会不会是因为我的 table 中的原始专栏?

提前致谢!

Oracle 12.2 引入了两个新的分区特性,它们将帮助您在这里获得很棒的交易。

  1. 引入了新的 ALTER TABLE MODIFY PARTITION BY DDL,允许将非分区 table 转换为分区 table。此操作会将数据从现有的未分区 table 复制到新的 table 分区中,因此它可以是 long-运行。您可以指定 ONLINE 关键字在联机模式下进行操作,这意味着 table 上的 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 问题,CREATE TABLE 中引入了 FOR EXCHANGE WITH TABLE 子句。这专门用于在创建将与现有 table 交换的新 table 时精确匹配物理列。可选地,FOR EXCHANGE WITH TABLE 可以与 PARTITION BY 一起使用来创建一个分区 table,可以与源 table 交换。例如:
    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 that describes both of these partitioning enhancements. And here is another blog article 专门讨论使用 CREATE TABLE ... FOR EXCHANGE WITH TABLE 解决 EXCHANGE PARTITION 错误。

您没有提到您使用的是哪个版本的 Oracle,所以您可能仍然是 运行 11g。在这种情况下,您可能需要深入研究 USER_TAB_COLS 以查看两个 table 之间的区别。您提到您已经检查了隐藏列(这很好),但可能会出现其他不匹配。

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

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

RAW(1000) 列对于 EXCHANGE PARTITION 应该不是问题。