【问题标题】:How to store NULL values in an interval partitioned table in Oracle?如何在 Oracle 的间隔分区表中存储 NULL 值?
【发布时间】:2018-07-05 20:20:28
【问题描述】:

我们使用分区来删除旧数据(Oracle 称之为ILM)。 有一列带有“最佳日期”,之后将删除分区。

为避免手动(或按脚本)添加分区,我们使用间隔分区:

CREATE TABLE my_table (
  id NUMBER NOT NULL PRIMARY KEY,
  --... other columns ...
  t DATE
) PARTITION BY RANGE (t) INTERVAL(NUMTODSINTERVAL(7, 'DAY')) (
  PARTITION PRE2018 VALUES LESS THAN (DATE '2018-01-01')
);

INSERT INTO my_table(id, t) VALUES (1, SYSDATE);
-- 1 row inserted.

... 工作正常,但我们不能将分区日期留给NULL

INSERT INTO my_table(id, t) VALUES (2, NULL);
-- ORA-14300: partitioning key maps to a partition outside maximum permitted number of partitions

如何解决?

【问题讨论】:

  • 您不能,如果您需要日期可以为空,您可能需要添加另一个日期列(例如 createDate 默认 SYSDATE)并在其上进行分区。
  • @BigMike 感谢您的确认。 createDate 不是一个选项,因为我们的列是删除日期(正如我在问题中所写)
  • 分区列中不可能有空值。您设置不为空,并在适用值中设置一些默认值,例如“01-01-1900”,将其分配给另一个临时分区
  • NULL as key for interval partitioning is not allowed NULL 值在使用间隔分区时不能存储在分区键列中。跨度>

标签: sql oracle oracle11g


【解决方案1】:

例如,您可以这样做:

CREATE TABLE my_table (
    ID NUMBER NOT NULL PRIMARY KEY,
    --... other columns ...
    t TIMESTAMP(0),
    PARTITION_KEY TIMESTAMP(0) GENERATED ALWAYS AS (COALESCE(t, TIMESTAMP '2999-01-01 00:00:00')) VIRTUAL
)
PARTITION BY RANGE (PARTITION_KEY) INTERVAL( NUMTODSINTERVAL(7, 'DAY')) ( 
    PARTITION PRE2018 VALUES LESS THAN (TIMESTAMP '2018-01-01 00:00:00')
);

应该像PARTITION FOR (TIMESTAMP '2999-01-01 00:00:00')这样简单地解决它

也许你也可以使用GENERATED ALWAYS AS (COALESCE(t, TIMESTAMP '1900-01-01 00:00:00')),这取决于更适合你的逻辑。

【讨论】:

  • 感谢您的回答,有趣的方法。出于兴趣,分区修剪是否适用于虚拟列? (在我们的例子中,该列是删除日期,因此该日期不太可能包含在查询中)。
  • 很可能不是,您需要修改查询,例如select * from my_table partition for (TIMESTAMP '2018-01-01 00:00:00') WHERE T = ...。但如果您在日期列上创建(本地)索引,它应该可以工作。
  • 顺便说一句,感谢您使用TIMESTAMP。在写这个 questino 之前阅读时,我偶然发现了 documentation 说只能使用 NUMBERDATE 进行间隔分区。你选择TIMESTAMP而不是DATE有什么原因吗?
  • @wolφi,不是真的,我只是习惯了。如果我处理INTERVAL 值,那么我更喜欢TIMESTAMP 数据类型。
  • @wolφi 对虚拟列进行修剪工作正常,您必须使用谓词中的虚拟列公式,例如:where COALESCE(t, TIMESTAMP '2999-01-01 00:00:00') = TIMESTAMP '2018-01-01 00:00:00'
猜你喜欢
  • 1970-01-01
  • 2013-07-22
  • 2014-10-19
  • 2019-01-10
  • 2017-04-14
  • 1970-01-01
  • 2015-09-23
  • 2016-03-05
  • 1970-01-01
相关资源
最近更新 更多