当处理大型表(2b行)的一些分区概念证明时,我们想出了一些奇怪的select语句行为:
create table date_test (
JOURNAL_ID VARCHAR2(10 BYTE) NOT NULL ENABLE,
JOURNAL_DATE DATE NOT NULL ENABLE
)
PARTITION BY RANGE (JOURNAL_DATE) INTERVAL (NUMTOYMINTERVAL(1,'MONTH'))
(
PARTITION P_20010101 VALUES LESS THAN (TO_DATE('20010101', 'YYYYMMDD'))
);
并在运行此查询时:
select * from date_test
WHERE (
JOURNAL_DATE < TO_DATE('20061201','YYYYMMDD')
OR
JOURNAL_DATE > TO_DATE('20061231','YYYYMMDD')
) ;
我收到以下错误:
ORA-01841 :(完整)年份必须介于-4713和9999之间,而不是0 01841. 00000 - “(完整)年份必须介于-4713和9999之间,而不是0 原因:非法年份输入行动:输入指定范围内的年份
“有趣”的是,如果你删除OR两边的一个子句,查询似乎启动好了 . 当然,查询在非分区表中正常工作 .
非常感谢任何帮助或指示 .
2 回答
这看起来像bug,可能是20961659或其亲戚之一 . 您可以通过更改the optimizer_features_enable setting来解决此问题,如果您不希望它更广泛地应用,您可以在查询中执行此操作:
在12.1.0.2.170117中,我看到与原始查询相同的错误;但有了这个提示,它按预期工作 .
当然要注意副作用,如果有疑问,您可以随时向Oracle支持部门提出服务请求 .
Read more in the documentation,并在My Oracle Support中探索与此错误相关的条目 .
在这种情况下,您似乎也可以通过将逻辑反转为使用
and
的包含日期范围来获得您想要的结果,并使用not
取消它;但你需要阻止优化器将其更改回来 - 这可能再次过度杀伤但是a no_query_transformation hint似乎可以解决这个问题:no_expand hint似乎没有帮助;虽然正如@WernfriedDomscheit建议的那样,未记载的
no_expand_table
提示确实似乎有所帮助 .尝试使用> =
或使用之间