首页 文章

Oracle 12c按区域间隔ORA-01841进行分区

提问于
浏览
0

当处理大型表(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 回答

  • 0

    这看起来像bug,可能是20961659或其亲戚之一 . 您可以通过更改the optimizer_features_enable setting来解决此问题,如果您不希望它更广泛地应用,您可以在查询中执行此操作:

    select /*+ optimizer_features_enable('12.1.0.1') */ * from date_test
     WHERE (
     JOURNAL_DATE < TO_DATE('20061201','YYYYMMDD')
     OR 
     JOURNAL_DATE > TO_DATE('20061231','YYYYMMDD')
     ) ;
    

    在12.1.0.2.170117中,我看到与原始查询相同的错误;但有了这个提示,它按预期工作 .

    当然要注意副作用,如果有疑问,您可以随时向Oracle支持部门提出服务请求 .

    Read more in the documentation,并在My Oracle Support中探索与此错误相关的条目 .


    在这种情况下,您似乎也可以通过将逻辑反转为使用 and 的包含日期范围来获得您想要的结果,并使用 not 取消它;但你需要阻止优化器将其更改回来 - 这可能再次过度杀伤但是a no_query_transformation hint似乎可以解决这个问题:

    select /*+ no_query_transformation */ * from date_test
     WHERE NOT (
     JOURNAL_DATE >= TO_DATE('20061201','YYYYMMDD')
     AND 
     JOURNAL_DATE <= TO_DATE('20061231','YYYYMMDD')
     ) ;
    

    no_expand hint似乎没有帮助;虽然正如@WernfriedDomscheit建议的那样,未记载的 no_expand_table 提示确实似乎有所帮助 .

  • 1

    尝试使用> =

    select * from date_test WHERE TO_DATE('20061201','YYYYMMDD')OR JOURNAL_DATE> = TO_DATE('20061231','YYYYMMDD'));(JOURNAL_DATE <

    或使用之间

    其中JOURNAL_DATE介于to_date('20061201','YYYYMMDD')和TO_DATE('20061231','YYYYMMDD')之间

相关问题