AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 56172
Accepted
Amir Pashazadeh
Amir Pashazadeh
Asked: 2014-01-06 05:07:03 +0800 CST2014-01-06 05:07:03 +0800 CST 2014-01-06 05:07:03 +0800 CST

Partição Oracle por intervalo usando calendário persa

  • 772

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 gregoriancalendário, não com o persiancalendário.

Existe alguma maneira de forçar o Oracle a usar calendários persas para criar novas partições?

oracle partitioning
  • 2 2 respostas
  • 3224 Views

2 respostas

  • Voted
  1. Best Answer
    Alex Poole
    2014-01-07T04:24:16+08:002014-01-07T04:24:16+08:00

    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:

    create table test_temp_times (
      id number(18) not null,
      xdate date not null,
      str varchar2(20),
      ydate as (to_number(to_char(xdate, 'YYYYMM', 'nls_calendar=persian')))
    )
    partition by range(ydate)
    interval(1)
    (partition p0 values less than (139201))
    enable row movement;
    

    Se isso for preenchido com um registro para todos os dias do ano seguinte à data de início do exemplo:

    insert into test_temp_times (id, xdate, str)
    select level, date '2013-03-20' + level, null
    from dual
    connect by level < 366;
    

    As partições criadas serão algo como:

    select table_name, partition_name, high_value
    from user_tab_partitions where table_name = 'TEST_TEMP_TIMES';
    
    TABLE_NAME                     PARTITION_NAME                 HIGH_VALUE
    ------------------------------ ------------------------------ ----------
    TEST_TEMP_TIMES                P0                             139201     
    TEST_TEMP_TIMES                SYS_P479                       139202     
    TEST_TEMP_TIMES                SYS_P480                       139203     
    TEST_TEMP_TIMES                SYS_P481                       139204     
    TEST_TEMP_TIMES                SYS_P482                       139205     
    TEST_TEMP_TIMES                SYS_P483                       139206     
    TEST_TEMP_TIMES                SYS_P484                       139207     
    TEST_TEMP_TIMES                SYS_P485                       139208     
    TEST_TEMP_TIMES                SYS_P486                       139209     
    TEST_TEMP_TIMES                SYS_P487                       139210     
    TEST_TEMP_TIMES                SYS_P488                       139211     
    TEST_TEMP_TIMES                SYS_P489                       139212     
    TEST_TEMP_TIMES                SYS_P490                       139213     
    
     13 rows selected 
    

    E você pode verificar em quais partições os limites do mês se enquadram:

    select utp.partition_name, min(ttt.xdate), max(ttt.xdate)
    from test_temp_times ttt
    join user_objects uo on uo.object_id = dbms_rowid.rowid_object(ttt.rowid)
    join user_tab_partitions utp on utp.table_name = uo.object_name
    and utp.partition_name = uo.subobject_name
    group by utp.partition_name
    order by partition_name;
    
    PARTITION_NAME                 MIN(TTT.XDATE) MAX(TTT.XDATE)
    ------------------------------ -------------- --------------
    P0                             2013-03-20     2013-03-20     
    SYS_P479                       2013-03-21     2013-04-20     
    SYS_P480                       2013-04-21     2013-05-21     
    SYS_P481                       2013-05-22     2013-06-21     
    SYS_P482                       2013-06-22     2013-07-22     
    SYS_P483                       2013-07-23     2013-08-22     
    SYS_P484                       2013-08-23     2013-09-22     
    SYS_P485                       2013-09-23     2013-10-22     
    SYS_P486                       2013-10-23     2013-11-21     
    SYS_P487                       2013-11-22     2013-12-21     
    SYS_P488                       2013-12-22     2014-01-20     
    SYS_P489                       2014-01-21     2014-02-19     
    SYS_P490                       2014-02-20     2014-03-19
    

    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:

    select * from test_temp_times
    where xdate = date '2013-11-01';
    

    Ele encontra a linha com o plano:


    -----------
    | Id  | Operation           | Name            | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
    -------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT    |                 |     1 |    47 |   164   (0)| 00:00:02 |       |       |
    |   1 |  PARTITION RANGE ALL|                 |     1 |    47 |   164   (0)| 00:00:02 |     1 |1048575|
    |*  2 |   TABLE ACCESS FULL | TEST_TEMP_TIMES |     1 |    47 |   164   (0)| 00:00:02 |     1 |1048575|
    -------------------------------------------------------------------------------------------------------
    

    Se eu adicionar explicitamente a coluna virtual à consulta:

    select * from test_temp_times
    where xdate = date '2013-11-01'
    and ydate = to_number(to_char(date '2013-11-01', 'YYYYMM', 'nls_calendar=persian'));
    

    Então ele sabe qual partição consultar:

    ----------------------------------------------------------------------------------------------------------
    | Id  | Operation              | Name            | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
    ----------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT       |                 |     1 |    47 |    14   (0)| 00:00:01 |       |       |
    |   1 |  PARTITION RANGE SINGLE|                 |     1 |    47 |    14   (0)| 00:00:01 |     9 |     9 |
    |*  2 |   TABLE ACCESS FULL    | TEST_TEMP_TIMES |     1 |    47 |    14   (0)| 00:00:01 |     9 |     9 |
    ----------------------------------------------------------------------------------------------------------
    

    Claramente, ainda não criei nenhum índice. Se você estiver procurando por dados de um mês inteiro, precisará consultar apenas um único ydatevalor e ignorar xdate; mas presumivelmente você precisaria de uma mistura pelo menos algumas vezes.

    • 5
  2. hmmftg
    2014-01-07T01:03:41+08:002014-01-07T01:03:41+08:00

    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:

    FUNCTION MONTH_DAYS (P_DATE IN DATE)
        RETURN NUMBER
    IS
        V_MONTH_ID   NUMBER;
    BEGIN
        V_MONTH_ID := TO_NUMBER (TO_CHAR (P_DATE, 'MM', 'NLS_CALENDAR=PERSIAN'));
    
        CASE V_MONTH_ID
            WHEN 1
            THEN
                RETURN 31;
                ...
        END CASE;
    END;
    
    • 1

relate perguntas

  • Backups de banco de dados no Oracle - Exportar o banco de dados ou usar outras ferramentas?

  • ORDER BY usando prioridades personalizadas para colunas de texto

  • Interface sqlplus confortável? [fechado]

  • Como encontrar as instruções SQL mais recentes no banco de dados?

  • Como posso consultar nomes usando expressões regulares?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve