我正在通过ETL工具运行并发插入查询(同时进行12个查询),以将数据插入Oracle的分区表中。
表定义为
CREATE TABLE CUST_TRAN
(
TRAN_SEQ_NO NUMBER(20,0)
, TRAN_DATE DATE
)
TABLESPACE USERS
STORAGE (INITIAL 256K NEXT 256K)
PARTITION BY RANGE (TRAN_DATE)
INTERVAL(NUMTODSINTERVAL(1, 'DAY'))
(
PARTITION CUST_TRAN_p_old VALUES LESS THAN (TO_DATE('1-1-2008', 'DD-MM-YYYY'))
)
这12个查询在4个不同的日期运行(每个日期3个查询)。因此,这12个查询正试图插入4个分区中。这是示例插入查询-
insert into cust_tran
select a.tran_seq_no, trunc(a.tran_datetime) as tran_date
from table_a a
inner join table_b b on a.store = b.store
and a.tran_seq_no = b.tran_seq_no
and trunc(a.tran_datetime) = to_date('2018-01-31', 'YYYY-MM-DD')
and a.tran_type in ('SALE')
但是,我一直遇到以下问题之一-
1)我收到此错误-ORA-14300: partitioning key maps to a partition outside maximum permitted number of partitions
或
2)作业运行正常,没有任何错误,但是将数据插入到CUST_TRAN_SUMM_p_old分区中,该日期具有任何源查询中都不存在的奇异日期,并且该日期在源表中不存在。奇怪的日期的确切值很难分辨,因为当我使用SQL Developer并将日期格式设置为YYYY-MM-DD HH24:MI:SS(在“工具”>“首选项”>“数据库”>“ NLS”中)时,它显示为空,但当我将显示格式更改为DD-MON-RR HH24:MI:SS时,它显示29-NOV-01 22:58:59。当我使用DBeaver时,它显示为10101-11-29 22:58:59。当我使用Toad for Oracle时,它显示为1/1/0001。
第一个问题真的很奇怪,因为我在过滤器中提供了日期,而且它无法获取不在过滤器中的另一个日期。另外,我是在重新创建表后运行此程序。因此,不可能达到最大分区数(1,023,999)。
第二个问题也很奇怪。
这是Oracle中的错误吗? Oracle中是否有一些需要更改的设置?使用并发插入查询将数据插入分区表是否错误?
答案 0 :(得分:0)
至少一件事似乎很清楚。您提到的错误是
ORA-14300: partitioning key maps to a partition outside maximum permitted number of partitions
在间隔分区表的分区键中插入值NULL
时发生。
简单尝试一下此插入
insert into CUST_TRAN (TRAN_SEQ_NO,TRAN_DATE) Values(1,null);
此问题没有简单的解决方法,通常使用一些奇怪的日期(例如01.01.2999)来代替缺少的日期-例如,参见here
在这里,我将开始调查-假设您观察到的奇怪的日期可以替代无效日期的缺失。
调查源数据库还不够,典型的ETL过程比简单的插入要复杂得多。您必须检查ETL脚本的代码,以查看是否有这种日期操作。
到您的观察日期10101-11-29
-允许的range for years排除10101作为一年。
Oracle数据库可以存储儒略时代的日期,范围是从公元前4712年1月1日到9999年12月31日(通用时代或“ AD”)。除非特别使用BCE(格式掩码中的“ BC”),否则默认为CE日期条目。
从事实来看,该日期位于old
分区中(即小于2008年),因此我认为它是29年11月-DATE'0029-11-01'
,而DAY则是在输出中与其他字符串串联。