Oracle supports Persian (Jalali) calendar in DDL queries, I can easily say:
select to_char(register_date, 'YYYY-MM-DD', 'nls_calendar=persian')
from my_table;
I created a table as:
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;
the table is created normally, but when I add records to it, and oracle creates new partitions, the partitions are:
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')));
as you can see, the database changed the NLS_CALENDAR to gregorian
(the same day as 13920101) and each partition is created according to gregorian
calendar, not persian
calendar.
Is there any way to force Oracle to use persian calendars for creating new partitions?
Best Answer
I don't see any way to have intervals that are defined in a different calendar than your database-level NLS_CALENDAR. You could get the same effect by partitioning on a numeric representation of the (Persian) month each date falls in, using a virtual column:
If that is populated with a record for every day for the year following your example start date:
The partitions that are created will look something like:
And you can check which partitions the month boundaries fall in:
At least, I think that's what you're trying to achieve... Unfortunately I can't add a demo as SQL Fiddle doesn't have the partitioning option, but this is tested against 11.2.0.3.
Of course, you have to make it use the partitions for the query... if I just do:
It finds the row with plan:
If I explicitly add the virtual column to the query:
Then it knows which partition to query:
Clearly I haven't created any indexes yet. If you are looking for a whole month's worth of data, you would only need to query on a single
ydate
value, and ignorexdate
; but presumably you'd need a mix at least some of the time.