Как удалить разделы на основе определенного срока хранения? - PullRequest
0 голосов
/ 15 января 2019
    PROCEDURE purge_partitions
   (
      p_owner            IN VARCHAR2
     ,p_name             IN VARCHAR2
     ,p_retention_period IN NUMBER
   ) IS
   BEGIN
      FOR partition_rec IN (SELECT partition_name
                                  ,high_value
                              FROM dba_tab_partitions
                             WHERE table_owner = p_owner
                               AND table_name = p_name)

      --drop partitions older than specified retention preriod
      LOOP
         IF SYSDATE >= add_months(to_date(substr(partition_rec.high_value
                                                ,12
                                                ,19)
                                         ,'YYYY-MM-DD HH24:MI:SS')
                                 ,p_retention_period)
         THEN
            execute_immediate('ALTER TABLE ' || p_owner || '.' ||
                              p_name || ' DROP PARTITION ' ||
                              partition_rec.partition_name);
         END IF;
      END LOOP;
   END purge_partitions;

Я пытаюсь добавить дополнительную детализацию в оператор цикла, чтобы вместо того, чтобы просто отбрасывать разделы ежемесячно, я бы хотел продлить это на несколько дней. Кроме того, только для справки, записи извлекаются из вкладки «Конфигурация», которая содержит сведения о секционированных таблицах (владелец таблицы, имя и срок хранения - тип данных NUMBER). Поэтому я не уверен, как это сделать. Любая помощь высоко ценится.

Ответы [ 2 ]

0 голосов
/ 16 января 2019

В вашей процедуре есть синтаксические ошибки (например, execute_immediate(...)).

Рабочая процедура будет такой. Вы должны назвать это drop_partitions, а не purge_partitions, потому что вы отбрасываете разделы. «Чистка» также возможна, с ALTER TABLE ... TRUNCATE PARTITION ...:

CREATE OR REPLACE PROCEDURE drop_partitions(
   p_owner IN VARCHAR2, 
   p_name IN VARCHAR2, 
   p_retention_period IN INTERVAL DAY TO SECOND) IS

    ts TIMESTAMP;

    CURSOR TabPartitions IS 
    SELECT partition_name, high_value 
    FROM dba_tab_partitions 
    WHERE table_owner = p_owner 
        AND table_name = p_name;

BEGIN

    FOR partition_rec IN TabPartitions LOOP 
        EXECUTE IMMEDIATE 'BEGIN :ret := '||partition_rec.HIGH_VALUE||'; END;' USING OUT ts;
        IF ts < SYSTIMESTAMP - p_retention_period THEN
            --drop partitions older than specified retention preriod
            EXECUTE IMMEDIATE 'ALTER TABLE ' || p_owner ||'.'||p_name 
                 || ' DROP PARTITION ' || partition_rec.partition_name || ' UPDATE GLOBAL INDEXES';
        END IF;
    END LOOP;

END drop_partitions;

Тогда вы можете вызвать эту процедуру, например, как

purge_partitions('OWNER_NAME', 'TABLE_NAME', INTERVAL '60' DAY);
purge_partitions('OWNER_NAME', 'TABLE_NAME', NUMTODSINTERVAL(100, 'day'));

Обратите внимание, у вас также есть YEAR TO MONTH INTERVAL в Oracle. Если вы хотите использовать это также, вы должны перегрузить процедуру, то есть создать вторую процедуру:

CREATE OR REPLACE PROCEDURE drop_partitions(
   p_owner IN VARCHAR2, 
   p_name IN VARCHAR2, 
   p_retention_period IN INTERVAL YEAR TO MONTH) IS

   ... rest would be exactly the same as above.

Имейте в виду, что для INTERVAL YEAR TO MONTH вы получаете исключения для вычислений, таких как timestamp '2019-03-31 00:00:00' - INTERVAL '1' MONTH, см. Арифметика даты и времени / интервала

0 голосов
/ 15 января 2019

ИМХО, столбец HIGH_VALUE имеет тип данных LONG, поэтому его довольно сложно использовать в PL / SQL.Но вам не нужно использовать это в любом случае, есть конструкция ALTER TABLE ... DROP PARTITION FOR (to_date (....)) .Таким образом, вам вообще не нужно иметь дело с сгенерированным именем раздела.

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

ALTER TABLE sales DROP PARTITION FOR(TO_DATE('01-SEP-2007','dd-MON-yyyy'));

PS: похоже, что это расширение SQL было запатентовано Oracle.

...