Plsql 如何仅选择pl/sql中应截断的分区

Plsql 如何仅选择pl/sql中应截断的分区,plsql,truncate,partition,Plsql,Truncate,Partition,给定2个具有值的变量: v_日1=30 v_days2=367 以及所有_选项卡_分区的以下分区: 如何在所有_tab_分区中选择不等于v_days1和v_days2的高_值,并截断相应的分区 对于此示例,将分区partitionname2_P60截断为partitionname1_P330 由于高值数据类型的长度很长,因此不能在where子句中直接使用它。您需要首先转换为lob,然后才能使用。然而,在这种情况下,使用它变得很困难,因为您必须在一个数字范围内查找。因此,您可以稍微修改解决方案,并

给定2个具有值的变量: v_日1=30 v_days2=367

以及所有_选项卡_分区的以下分区:

如何在所有_tab_分区中选择不等于v_days1和v_days2的高_值,并截断相应的分区

对于此示例,将分区partitionname2_P60截断为partitionname1_P330

由于高值数据类型的长度很长,因此不能在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;

来自所有\u选项卡\u分区的高\u值具有长数据类型。我尝试了你的建议,但得到了错误:PL/SQL:ORA-00997:非法使用长数据类型和PLS-00364:循环索引变量'REC'的使用是错误的invalid@dcdum2018如果语句没有截断分区,请阅读我的评论并查看修改后的答案。v_days1和v_days2是高_值,其分区不应被截断,而其余分区应被截断。对于此示例,不应截断高_值=30和367的分区,而应截断高_值=60到330的分区。@dcdum2018我想您应该根据需要修改代码。请查看更新的答案。我只是举了一个例子,展示了如何实现您的需求。
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>
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;