Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何在Oracle中的间隔分区表中存储空值?_Sql_Oracle_Oracle11g - Fatal编程技术网

Sql 如何在Oracle中的间隔分区表中存储空值?

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

我们使用分区来删除旧数据(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')) (
  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'