我正在通过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中)时,它显示为null但是当我将显示格式更改为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中是否有一些需要更改的设置?使用并发插入查询将数据插入分区表是错误的吗?
至少有一点似乎很清楚。你提到的错误是
ORA-14300: partitioning key maps to a partition outside maximum permitted number of partitions
当您在区间分区表的分区键中插入值NULL
时会发生这种情况。
简单试试这个INSERT
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日(Common Era,或'AD')。除非专门使用BCE(格式掩码中的'BC'),否则CE日期条目是默认值。
事实上,这个日期是在old
分区(即少于2008年),我假设它是29年的11月 - DATE'0029-11-01'
和DAY以某种方式与输出上的其他字符串连接。