Oracle 在 DDL 查询中支持波斯 (Jalali) 日历,我可以轻松地说:
select to_char(register_date, 'YYYY-MM-DD', 'nls_calendar=persian')
from my_table;
我创建了一个表:
create table test_temp_times (
id number(18) not null,
xdate date not null,
str varchar2(20))
partition by range(xdate)
interval(NUMTOYMINTERVAL(1, 'MONTH'))
(partition p0 values less than (to_date('13920101', 'YYYYMMDD', 'nls_calendar=persian')))
enable row movement;
该表是正常创建的,但是当我向其中添加记录并且 oracle 创建新分区时,分区是:
create table TEMP_TIMES (
id NUMBER(18) not null,
xdate DATE not null,
str VARCHAR2(20)
)
partition by range (XDATE)
(
partition P0 values less than (TO_DATE(' 2013-03-21 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')),
partition SYS_P61 values less than (TO_DATE(' 2013-04-21 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')),
partition SYS_P62 values less than (TO_DATE(' 2013-05-21 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')),
partition SYS_P63 values less than (TO_DATE(' 2013-06-21 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')),
partition SYS_P64 values less than (TO_DATE(' 2013-07-21 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')));
如您所见,数据库将 NLS_CALENDAR 更改为gregorian
(与 13920101 同一天)并且每个分区都是根据gregorian
日历而不是persian
日历创建的。
有什么方法可以强制 Oracle 使用波斯日历来创建新分区?
我看不出有任何方法可以在与数据库级 NLS_CALENDAR 不同的日历中定义间隔。您可以通过使用虚拟列对每个日期所在的(波斯)月份的数字表示进行分区来获得相同的效果:
如果在示例开始日期之后的一年中的每一天都填充了记录:
创建的分区如下所示:
您可以检查月份边界属于哪些分区:
至少,我认为这就是您想要实现的目标......不幸的是,我无法添加演示,因为 SQL Fiddle 没有分区选项,但这是针对 11.2.0.3 进行的测试。
当然,你必须让它使用分区进行查询......如果我只是这样做:
它找到带有计划的行:
如果我将虚拟列显式添加到查询中:
然后它知道要查询哪个分区:
显然我还没有创建任何索引。如果您正在寻找一整月的数据,您只需要查询一个
ydate
值,然后忽略xdate
; 但大概你至少在某些时候需要混合。萨拉姆!您对 oracle 说要使用 30 天的间隔,因此它将该间隔添加到 sysdate 并使用它!我认为您最好使用 numtodsinterval(month_days(column_name), 'DAY') 而不是 numtodsinterval(1, 'MONTH') 哪个 month_days 计算波斯月的天数,如下所示: