如何在加载数据之前使分区Oracle表的所有索引对当前分区不可用

rdrgkggo  于 2023-11-17  发布在  Oracle
关注(0)|答案(1)|浏览(136)

我有一个已分区的Oracle表,它是按日期列分区的。我想在为当前分区加载数据之前使所有索引不可用,然后使它们重建。我使用此查询重建所有索引,本地/全局:

DECLARE
  v_table_owner VARCHAR2(30) := 'TEST_USER';
  v_table_name VARCHAR2(30) := 'TEST_TABLE';
  BEGIN 
  -- Rebuild unusable indexes for the specified table  
  FOR rec_index IN (
   SELECT owner,
        index_name
        FROM   all_indexes WHERE  table_name = v_table_name
   AND    status = 'UNUSABLE')   
  LOOP    
   EXECUTE IMMEDIATE 'ALTER INDEX ' || rec_index.owner || '.' || rec_index.index_name || ' REBUILD';
  END LOOP;
  -- Rebuild unusable partitions for the specified table using the view
 FOR rec_partition IN (
  SELECT aip.index_owner,
       aip.index_name,
       aip.partition_name
   FROM   all_ind_partitions aip 
       JOIN all_tab_partitions ait
       ON     aip.index_owner = ait.table_owner
          AND aip.index_name = ait.table_name 
    WHERE  aip.status = 'UNUSABLE' AND    table_name = v_table_name)
   LOOP
    BEGIN
     EXECUTE IMMEDIATE
      'ALTER INDEX ' || rec_partition.index_owner || '.' || rec_partition.index_name
      || ' REBUILD PARTITION ' || rec_partition.partition_name;
     EXCEPTION
     WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(sqlerrm);
    END;
   END LOOP;

字符串
另外,我使用这个查询来使索引不可用

DECLARE
  v_table_owner VARCHAR2(30) := 'TEST_USER'; 
  v_table_name VARCHAR2(30) := 'TEST_TABLE';  
  v_partition_date DATE := TO_DATE('2023-11-01', 'YYYY-MM-DD'); 
     BEGIN
     SELECT partition_name INTO v_partition_name FROM all_tab_partitions
      WHERE table_owner = v_table_owner AND table_name = v_table_name AND TO_DATE(partition_name, 'YYYY-MM-DD') = v_partition_date;
 -- Disable indices for the current partition
 FOR rec_index IN (SELECT owner, index_name
      FROM all_indexes
      WHERE table_name = v_table_name)
    LOOP
   EXECUTE IMMEDIATE 'ALTER INDEX ' || rec_index.owner || '.' || 
  rec_index.index_name || ' UNUSABLE PARTITION ' || v_partition_name;
  END LOOP;
 END;


第二个查询有此错误:

Error report -
  ORA-06550: line 8, column 8:
  PLS-00201: identifier 'V_PARTITION_NAME' must be declared
  ORA-06550: line 9, column 3:
  PL/SQL: ORA-00904: : invalid identifier
  ORA-06550: line 7, column 3:
  PL/SQL: SQL Statement ignored
  ORA-06550: line 20, column 49:
  PLS-00201: identifier 'V_PARTITION_NAME' must be declared
  ORA-06550: line 19, column 5:
  PL/SQL: Statement ignored
  06550. 00000 -  "line %s, column %s:\n%s"
  *Cause:    Usually a PL/SQL compilation error.

更新这是创建表格的脚本:

CREATE TABLE test_table
     ("INSERT_DATE_TIME" VARCHAR2(30 BYTE), 
        "NAME" VARCHAR2(30 BYTE), 
        "ID" VARCHAR2(50 BYTE), 
        "T_DATE" DATE
     CONSTRAINT "test_table" PRIMARY KEY ("ID", "T_DATE")  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS NOLOGGING    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
 TABLESPACE "USERS"  ENABLE) PCTFREE 0 PCTUSED 0 INITRANS 1 
MAXTRANS 255 
  COMPRESS BASIC  NOLOGGING 
   STORAGE(
   BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
   TABLESPACE "USERS" 
   PARTITION BY RANGE ("T_DATE") INTERVAL (NUMTODSINTERVAL(1,'DAY')) 
   (PARTITION "SYS_P18549"  VALUES LESS THAN (TO_DATE(' 2021-03-21 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))   NO INMEMORY SEGMENT CREATION DEFERRED PCTFREE 0 PCTUSED 0 INITRANS 1 MAXTRANS 255 
    COMPRESS BASIC NOLOGGING STORAGE( BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
     TABLESPACE "USERS" );


问题是如何运行上述查询当前分区,我的意思是当前日期?
任何帮助真的很感激。

kxe2p93d

kxe2p93d1#

您似乎想将第一段代码的第二部分合并组合起来,并在其中使用第二段代码中的EXECUTE IMMEDIATE语句:

DECLARE
  v_table_owner VARCHAR2(30) := 'TEST_USER';
  v_table_name VARCHAR2(30) := 'TEST_TABLE';
BEGIN 
  FOR rec_partition IN (
    SELECT aip.index_owner,
           aip.index_name,
           aip.partition_name
    FROM   all_ind_partitions aip 
           INNER JOIN all_tab_partitions ait
           ON     aip.index_owner = ait.table_owner
              AND aip.index_name = ait.table_name 
    WHERE  aip.index_owner =  v_table_owner
    AND    aip.index_name  =  v_table_name
    AND    aip.status      != 'UNUSABLE'
  )
  LOOP
    BEGIN
      EXECUTE IMMEDIATE
        'ALTER INDEX ' || rec_partition.index_owner || '.' || rec_partition.index_name
          || ' MODIFY PARTITION ' || rec_partition.partition_name || ' UNUSABLE';
    EXCEPTION
      WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE(sqlerrm);
    END;
  END LOOP;
END;
/

字符串

  • 注意:您可以排除所有已经无法使用的分区。*

相关问题