Как выбрать только те разделы, которые должны быть усечены в pl / sql - PullRequest
0 голосов
/ 20 сентября 2018

Имеются 2 переменные со значениями:
v_days1 = 30 v_days2 = 367

и ниже разделов из ALL_TAB_PARTITIONS:

TABLE_NAME  PARTITION_NAME        HIGH_VALUE (LONG datatype)
TABLENAME   partitionname1_P30    30
TABLENAME   partitionname2_P60    60 
TABLENAME   partitionname3_P90    90
TABLENAME   partitionname4_P120   120
TABLENAME   partitionname5_P150   150
TABLENAME   partitionname6_P180   180 
TABLENAME   partitionname7_210    210
TABLENAME   partitionname8_P240   240
TABLENAME   partitionname9_P270   270
TABLENAME   partitionname10_P300  300
TABLENAME   partitionname11_P330  330
TABLENAME   partitionname12_P360  367

Как выбрать HIGH_VALUE, которые не равны v_days1 и v_days2 в all_tab_partitions и обрезать соответствующие разделы?

Для этого примера обрезать разделы partitionname2_P60 до partitionname11_P330.

FOR rec IN (SELECT TABLE_NAME, PARTITION_NAME, HIGH_VALUE       
        FROM ALL_TAB_PARTITIONS 
        WHERE TABLE_NAME='TABLENAME'
        AND HIGH_VALUE NOT IN (v_days1, v_days2) LOOP

        <TRUNCATE PARTITIONS WITH HIGH_VALUE 60 TO 333 
        /TRUNCATE PARTITIONS WITH HIGH_VALUE NOT EQUAL TO 30 AND 367>

1 Ответ

0 голосов
/ 20 сентября 2018

Поскольку тип данных high_value имеет Long, вы не можете напрямую использовать его в предложении where.Вы должны сначала преобразовать в lob, а затем использовать.Однако в этом случае его становится трудно использовать, поскольку вам приходится искать между диапазонами чисел.Таким образом, вы можете немного изменить решение и выполнить ваши требования, как показано ниже:

DECLARE
  v_days1 varchar2(10) := '20';
  v_days2 varchar2(10) := '367';
  l_var    VARCHAR2(32767);
  v_sql   VARCHAR2(100);
BEGIN
  FOR rec IN
  (SELECT table_name,
    partition_name,
    high_value
  FROM all_tab_partitions
  WHERE TABLE_NAME='TABLENAME'
 --WHERE high_value NOT IN  ( v_days1)
  )
  LOOP
    l_var:=rec.high_value;
    --dbms_output.put_line('partition Name'||rec.partition_name);

    --IF l_var between '20' and '367' THEN   
      IF (l_var NOT IN (v_days1 ,v_days2)) THEN  
      dbms_output.put_line('partition Name'||rec.partition_name);
      v_sql:= 'ALTER TABLE '||rec.table_name||' TRUNCATE PARTITION '||rec.partition_name ;

      EXECUTE immediate v_sql ;
   END IF;
  END LOOP;
END;
...