Как партиционировать таблицу по диапазону для текущей недели?

Нужно партиционировать таблицу, а именно на три партиции в соответствии с колонкой EVENT_TIME, где первая партиция - это неделя от сегодняшнего дня, вторая - прошлая неделя, а третья партиция - это история, куда помещаются данные, не прошедшие в первые две партиции.

Кроме того, нужно добавить триггер, который будет очищать историю каждые две недели.

То есть, нужно нечто такое:

CREATE TABLE EVENTS_LOG_TEST_PARTITION (
    ID         NUMBER,
    METHOD     NVARCHAR2(100),
    INPUT      CLOB,
    EVENT_TIME TIMESTAMP(6),
    STATUS     NVARCHAR2(100),
    MESSAGE    NVARCHAR2(200))
PARTITION BY RANGE (EVENT_TIME) (
    PARTITION CURRENT_WEEK VALUES LESS THAN (TO_DATE(TO_CHAR(CURRENT_TIMESTAMP), 'dd-MM-yyyy HH24:mi:ss'))
) ENABLE ROW MOVEMENT;

Error report -
ORA-14019: partition bound element must be one of: string, datetime or interval literal, number, or MAXVALUE

Понимаю, что это не совсем корректно, потому что нельзя ссылаться на CURRENT_TIMESTAMP.

Как можно тогда создaть партицию для текущей недели?


Свободный перевод вопроса Oracle partitioning by range от участника @Limbo1111


Ответы (1 шт):

Автор решения: 0xdb

Похоже, что стоит задача - хранить данные за 2-3 недели. В этом случае, можно воспользоваться партиционированием по интервалу, и удалять самую старую партицию каждую неделю.

Партиционирование по интервалу создаст новую партицию каждый раз, когда вставляется запись со значением, превышающим текущую самую высокую границу партиции (high_value).

Все, что нужно определить, это начальную партицию и временной интервал. В качестве границы начальной партиции можно выбрать любое значение в прошлом.

Например:

create table events_log_test_partition (
    id         number,
    method     nvarchar2(100),
    input      clob,
    event_time timestamp(6),
    status     nvarchar2(100),
    message    nvarchar2(200)
) partition by range (event_time) interval ( interval '7' day ) (
    partition p_init values less than (date'2000-01-01'))
/    
insert into events_log_test_partition values (1, 'test', 'test', systimestamp - 14, 'test', 'test');
insert into events_log_test_partition values (2, 'test', 'test', systimestamp,      'test', 'test');

select partition_name, high_value 
from user_tab_partitions
where table_name = 'EVENTS_LOG_TEST_PARTITION';

PARTITION_NAME   HIGH_VALUE                      
---------------- --------------------------------
P_INIT           TIMESTAMP' 2000-01-01 00:00:00' 
SYS_P11141       TIMESTAMP' 2021-09-25 00:00:00' 
SYS_P11144       TIMESTAMP' 2021-10-09 00:00:00' 

Теперь, определить самую старшию партицию и удалить ее:

select event_time from events_log_test_partition partition for (date'2021-10-06' - 14);
  
EVENT_TIME
---------------------------
22.09.21 01:12:43,000000000

alter table events_log_test_partition
    drop partition for (date'2021-09-21');

Table EVENTS_LOG_TEST_PARTITION altered.

select partition_name, high_value 
from   user_tab_partitions
where  table_name = 'EVENTS_LOG_TEST_PARTITION';

PARTITION_NAME   HIGH_VALUE                      
---------------- --------------------------------
P_INIT           TIMESTAMP' 2000-01-01 00:00:00' 
SYS_P11144       TIMESTAMP' 2021-10-09 00:00:00' 

Свободный перевод ответа от участника @Chris Saxon

→ Ссылка