在11g中保持日间隔间隔的最佳方法

时间:2013-11-13 07:50:19

标签: sql oracle oracle11g partitioning database-partitioning

我在11g中创建了一个sql脚本,它会丢弃数据库中所有分区表中值小于60天的所有分区

DECLARE
   TNAME      VARCHAR2 (300);
   PNAME      VARCHAR2 (300);
   HIGHVAL    VARCHAR2 (3000);
   POSITION   SMALLINT;
   VAL        LONG;

   CURSOR C1
   IS
      SELECT TABLE_NAME, PARTITION_NAME, PARTITION_POSITION, HIGH_VALUE
        FROM USER_TAB_PARTITIONS
       WHERE TABLE_NAME NOT LIKE '%$%'
         AND TABLE_NAME NOT LIKE 'BIN%';
BEGIN
   OPEN C1;

   LOOP
      FETCH C1
       INTO TNAME, PNAME, POSITION, VAL;

      HIGHVAL := VAL;
      EXIT WHEN C1%NOTFOUND;

      IF TO_DATE (SUBSTR (HIGHVAL, 10, 11), 'RRRR-MM-DD') <
                                                          TRUNC (SYSDATE)
                                                          - 60
      THEN
         IF POSITION = 1
         THEN
            DBMS_OUTPUT.PUT_LINE ('ALTER TABLE ' || TNAME
                                  || ' SET INTERVAL();'
                                 );
         END IF;

         DBMS_OUTPUT.PUT_LINE (   'ALTER TABLE '
                               || TNAME
                               || ' DROP PARTITION '
                               || PNAME
                               || ' UPDATE GLOBAL INDEXES PARALLEL 2;'||CHR(10)
                               || '--DROPPED'
                               || '--'
                               || TO_DATE (SUBSTR (HIGHVAL, 10, 11),
                                           'RRRR-MM-DD'
                                          )
                              );

         IF POSITION = 1
         THEN
            DBMS_OUTPUT.PUT_LINE
                                (   'ALTER TABLE '
                                 || TNAME
                                 || ' SET INTERVAL(NUMTODSINTERVAL(1,''DAY''));'
                                );
         END IF;
      END IF;
   END LOOP;

   COMMIT;

   CLOSE C1;
END;
/

我正在执行生成的SQL文本

请提出建议,如果这是正确的,还有任何增强空间???

1 个答案:

答案 0 :(得分:1)

一些提示:

  • 这是隐式游标的理想之处,因此您无需手动声明变量,获取,打开和放大。关闭,...
  • 在查询中过滤较高的值,之前更好
  • 使用EXECUTE IMMEDIATE应用更改而不是手动执行打印的内容
  • 您不需要提交,因为它都是DDL

代码:

BEGIN
  FOR p IN (SELECT TABLE_NAME, PARTITION_NAME, PARTITION_POSITION, HIGH_VALUE
            FROM USER_TAB_PARTITIONS
            WHERE TABLE_NAME NOT LIKE '%$%'
            AND TABLE_NAME NOT LIKE 'BIN%'
            AND TO_DATE (SUBSTR (HIGH_VALUE, 10, 11), 'RRRR-MM-DD') < TRUNC (SYSDATE) - 60)
  LOOP
    IF p.PARTITION_POSITION = 1
    THEN
      EXECUTE IMMEDIATE 'ALTER TABLE ' || p.TABLE_NAME || ' SET INTERVAL()';
    END IF;

    EXECUTE IMMEDIATE 'ALTER TABLE ' || p.TABLE_NAME
                   || 'DROP PARTITION ' || p.PARTITION_NAME
                   || ' UPDATE GLOBAL INDEXES PARALLEL 2';

    IF p.PARTITION_POSITION = 1
    THEN
      EXECUTE IMMEDIATE 'ALTER TABLE ' || p.TABLE_NAME
                     || ' SET INTERVAL(NUMTODSINTERVAL(1,''DAY''));';
    END IF;
  END LOOP;
END;
/

还有一些警告:

  • 注意UPDATE GLOBAL INDEXES,它不适用于IOT表(如果你使用它们) (我错了这个)
  • 注意重置/设置间隔。一般规则是您不能删除最后一个非间隔分区。猜测这将是位置1是有风险的。最好依赖user_tab_partitions.interval标志。