【问题标题】:Oracle : Drop multiple partitionsOracle:删除多个分区
【发布时间】:2015-11-13 15:57:23
【问题描述】:

一张表TMP有5个分区,分别是P_1、P_2、....P_5。 我需要删除一些 TMP 的分区;要删除的分区是由另一个查询派生的。

例如:

ALTER TABLE TMP DROP PARTITIONS (SELECT ... From ...  //expression to get partition names )

假设 SELECT 语句返回 P_1 和 P_5。上面 ALTER 语句的部分查询不起作用。有什么方法可以删除来​​自 SELECT 语句的输入的分区?

【问题讨论】:

  • 为此你必须使用 pl/sql 块。

标签: oracle database-partitioning partition


【解决方案1】:

您可以在anonymous pl/sql 块中使用dynamic sql

Begin
  for i in (select part_name from ...  //expression to get partition names) loop
    execute immediate 'ALTER TABLE TMP DROP PARTITION ' || i.part_name;
  end loop;
end;

用于同时删除多个分区;

declare
  v_part varchar(1000);
Begin
  select LISTAGG(partition_name, ', ') WITHIN GROUP (ORDER BY partition_name DESC)
  into v_part  
  from ...  //expression to get partition names;
  execute immediate 'ALTER TABLE TMP DROP PARTITION ' || v_part;
end;

【讨论】:

    【解决方案2】:

    您需要使用动态 SQL。这个:

    begin
        for prec in (SELECT ... From ...  //expression to get partition names )
        loop
             execute immediate 'ALTER TABLE TMP DROP PARTITION '
                 || prec.partition_name;
        end loop;
    end;
    /
    

    显然,您需要完全相信您的查询将只返回您想要删除的分区。或者对您的备份和恢复计划有同等的信心:)

    或者,您可以使用类似的方法生成一个放置脚本,您可以在运行之前对其进行查看。

    【讨论】:

      【解决方案3】:

      您必须使用 pl/sql 块通过选择查询从表中删除分区。使用 listagg 制作一个逗号分隔的列表。

       DECLARE
          var1 varchar2(50);
          BEGIN
          SELECT listagg(Partition_names) into var1  from table_name//expression to get partition names ;
          execute immediate 'alter table tmp drop PARTITION'||var1  ;
          END;
      

      listagg 上的示例

      select LISTAGG(partition_name,',') within group(order by table_name) as comma_list
       from ALL_TAB_PARTITIONS where TABLE_owner='OWNER' AND TABLE_NAME='TABLE_NAME'
      

      【讨论】:

        【解决方案4】:

        您可以使用以下 sql 生成 DML 以删除多个表分区。

        select 'ALTER TABLE ' || TABLE_OWNER || '.' || TABLE_NAME || ' DROP PARTITION ' || '"' || PARTITION_NAME || '";' from DBA_TAB_PARTITIONS 
        where TABLE_NAME='%YOUR_PATTERN%'order by PARTITION_NAME;
        

        【讨论】:

        • 我不知道为什么这被否决了,我觉得这很有帮助。
        【解决方案5】:

        也许有人可以帮忙。

        此脚本删除特定架构的所有分区表的所有分区。我将它与带有 METADATA 的 clear DB 一起使用,用于更改已启动的(参考)分区。

        ALTER TABLE SCHEMA_1.TABLE_1
          SET INTERVAL ();
        ALTER TABLE SCHEMA_1.TABLE_2
          SET INTERVAL ();
        ALTER TABLE SCHEMA_1.TABLE_3
          SET INTERVAL ();  
        
        set lines 100
        
        set heading off
        
        spool runme.sql
        
        select 'ALTER TABLE ' || TABLE_OWNER || '.' || TABLE_NAME || ' DROP PARTITION ' || '"' || PARTITION_NAME || '";' from DBA_TAB_PARTITIONS 
        where 
            TABLE_OWNER='SCHEMA_1'
        --    and TABLE_NAME='TABLE_%' 
            and PARTITION_NAME LIKE 'SYS_P%'
            ;
        
        @runme
        
        ALTER TABLE SCHEMA_1.TABLE_1
          SET INTERVAL (NUMTOYMINTERVAL(1,'MONTH'));
        ALTER TABLE SCHEMA_1.TABLE_1
          SET INTERVAL (NUMTOYMINTERVAL(1,'MONTH'));
        ALTER TABLE SCHEMA_1.TABLE_3
          SET INTERVAL (NUMTOYMINTERVAL(1,'MONTH'));
        

        是的,脚本是半手动的,但我认为这样更安全。

        ALTER TABLE ... INTERVAL 需要删除最后一个分区。

        间隔必须与之前相同

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-09-04
          • 1970-01-01
          • 1970-01-01
          • 2021-11-22
          • 1970-01-01
          • 2015-05-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多