Sql 如何在Oracle中的间隔分区表中存储空值?
我们使用分区来删除旧数据(Oracle称之为分区)。 有一列带有“best before date”,在该列之后将删除分区 为了避免手动(或按脚本)添加分区,我们使用间隔分区:Sql 如何在Oracle中的间隔分区表中存储空值?,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,我们使用分区来删除旧数据(Oracle称之为分区)。 有一列带有“best before date”,在该列之后将删除分区 为了避免手动(或按脚本)添加分区,我们使用间隔分区: CREATE TABLE my_table ( id NUMBER NOT NULL PRIMARY KEY, --... other columns ... t DATE ) PARTITION BY RANGE (t) INTERVAL(NUMTODSINTERVAL(7, 'DAY')) ( PAR
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
如何解决这个问题 您可以这样做,例如:
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')那样简单地处理它。
也许你也可以使用
生成的ALWAYS AS(COALESCE(t,TIMESTAMP'1900-01-01 00:00:00'))
,这取决于什么更适合你的逻辑。你不能,如果你需要日期为空,你可能需要添加另一个日期列(例如createDate default SYSDATE)和分区。@BigMike谢谢你的确认。createDate不是一个选项,因为我们的列是删除日期(正如我在问题中所写的)null,在分区列中不可能。您在“01-01-1900”等适用值中设置了not null和默认值,并将其分配给另一个temp partitionNULL as key for interval partitioning is not null在使用间隔分区时,值不能存储在分区键列中。感谢您的回答,这是一种有趣的方法。出于兴趣,分区修剪会对虚拟列起作用吗?(在我们的例子中,该列是删除日期,因此查询中不太可能包含该日期)。最有可能的情况是,您需要修改查询,例如,select*from my_table partition for(TIMESTAMP'2018-01-01 00:00:00'),其中T=…
。但是如果您在日期列上创建一个(本地)索引,它应该可以工作。顺便说一句,感谢您使用时间戳
。在写这个问题之前,我读了一遍,无意中发现了这样一句话:只能使用NUMBER
或DATE
进行区间划分。你为什么选择时间戳而不是日期,这是有原因的吗?@wolφi,不是真的,我只是习惯了。如果我处理INTERVAL
值,那么我更喜欢TIMESTAMP
数据类型。@wolφI修剪虚拟列wor fine,您必须在谓词中使用虚拟列公式,例如:where COALESCE(t,TIMESTAMP'2999-01-01 00:00')=TIMESTAMP'2018-01-01 00:00'