O Oracle oferece suporte ao calendário persa (Jalali) em consultas DDL, posso dizer facilmente:
select to_char(register_date, 'YYYY-MM-DD', 'nls_calendar=persian')
from my_table;
Eu criei uma tabela como:
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;
a tabela é criada normalmente, mas quando adiciono registros a ela, e o oracle cria novas partições, as partições são:
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')));
como você pode ver, o banco de dados mudou o NLS_CALENDAR para gregorian
(o mesmo dia que 13920101) e cada partição é criada de acordo com o gregorian
calendário, não com o persian
calendário.
Existe alguma maneira de forçar o Oracle a usar calendários persas para criar novas partições?
Não vejo nenhuma maneira de ter intervalos definidos em um calendário diferente do seu NLS_CALENDAR no nível do banco de dados. Você pode obter o mesmo efeito particionando uma representação numérica do mês (persa) em que cada data se enquadra, usando uma coluna virtual:
Se isso for preenchido com um registro para todos os dias do ano seguinte à data de início do exemplo:
As partições criadas serão algo como:
E você pode verificar em quais partições os limites do mês se enquadram:
Pelo menos, acho que é isso que você está tentando alcançar... Infelizmente, não posso adicionar uma demonstração, pois o SQL Fiddle não tem a opção de particionamento, mas foi testado em 11.2.0.3.
Claro, você tem que usar as partições para a consulta ... se eu apenas fizer:
Ele encontra a linha com o plano:
Se eu adicionar explicitamente a coluna virtual à consulta:
Então ele sabe qual partição consultar:
Claramente, ainda não criei nenhum índice. Se você estiver procurando por dados de um mês inteiro, precisará consultar apenas um único
ydate
valor e ignorarxdate
; mas presumivelmente você precisaria de uma mistura pelo menos algumas vezes.Salam! Você disse ao oracle para usar um intervalo de 30 dias, então ele adiciona esse intervalo ao sysdate e usa isso! Acho que em vez de numtodsinterval(1, 'MONTH') é melhor usar numtodsinterval(month_days(column_name), 'DAY') que months_days calcula o número de dias do mês persa assim: