2017-01-03 5 views
1

Я буду использовать автоматическое разбиение на разделы с Oracle 11g, и мне интересно, есть ли какой-либо вариант, чтобы указать шаблон с названием раздела?Автоматическое разбиение на Oracle - шаблон имени для разделов

Например, у меня есть:

create table 
pos_data ( 
    start_date  DATE, 
    store_id   NUMBER, 
    inventory_id  NUMBER(6), 
    qty_sold   NUMBER(3), 
) 
PARTITION BY RANGE (start_date) 
INTERVAL(NUMTOYMINTERVAL(1, 'MONTH')) 
( 
    PARTITION pos_data_init VALUES LESS THAN (TO_DATE('01-01-2017', 'DD-MM-YYYY')), 
    PARTITION pos_data_201702 VALUES LESS THAN (TO_DATE('01-02-2017', 'DD-MM-YYYY')), 
    PARTITION pos_data_201703 VALUES LESS THAN (TO_DATE('01-03-2017', 'DD-MM-YYYY')), 
); 

Я есть раздел инициализации, чтобы все строки до 2017 года, а затем разделы для каждого месяца.

Как будут называться разделы, которые будут автоматически сгенерированы? Есть ли шанс создать шаблон, который будет означать, что конец имени будет YYYYMM? Или мне нужно переименовать эти разделы позже?

+2

Вы можете использовать PLSQL с динамическим SQL для архивации на основе шаблона naming – GurV

+0

Так что есть только scirpt-way, и автоматически сгенерированные имена просто нажимают на значение как на части, так и на part1, part2, part3 и т. Д.? – Sarpens

+1

@Sarpens, если вы используете разделение интервалов, тогда вы застреваете с именами, которые генерируются базой данных. Как предлагает GurV, если вам нужен определенный шаблон именования, вам нужно будет написать свой собственный код, чтобы ретроспективно переименовать разделы – Boneist

ответ

4

Нет, нет такой опции, которая позволяет указать шаблон имени раздела для динамически создаваемых разделов. Вы можете/должны переименовать их позже, если возникнет такая необходимость. Лично я не вижу необходимости переименовывать их. если вы хотите, чтобы дать тем, автоматически сгенерированных перегородок осмысленные имена, так что вы можете ссылаться на них в запросе, например:

select * 
    from partitioned_table 
    partition (part_1); 

, то вы можете легко использовать partition for (<<date>>) пункт для запроса конкретного раздела, который не требует, чтобы вы знали имя раздела вы хотите запросить:

select * 
    from partitioned_table 
    partition for (date '2017-01-01') 
+1

Теперь я получаю все это! Спасибо за ответ! Просто старый способ разбиения, который я рассматривал здесь, создавал с определенным шаблоном имени и просто задавался вопросом, могу ли я получить тот же результат с автоматическим способом. С наилучшими пожеланиями на Новый Год:) – Sarpens

1

Я использую эту процедуру переименования разделов, который выполняется один раз в день с помощью планировщика работы:

FUNCTION DailyPartition(tableName IN VARCHAR2) RETURN BOOLEAN IS 

    EXPRESSION_IS_OF_WRONG_TYPE EXCEPTION; 
    PRAGMA EXCEPTION_INIT(EXPRESSION_IS_OF_WRONG_TYPE, -6550); 

    ds INTERVAL DAY TO SECOND; 
    ym INTERVAL YEAR TO MONTH; 
    str VARCHAR2(1000); 

BEGIN  
    SELECT INTERVAL INTO str 
    FROM USER_PART_TABLES 
    WHERE TABLE_NAME = tableName; 

    EXECUTE IMMEDIATE 'BEGIN :ret := '||str||'; END;' USING OUT ym; 
    RETURN FALSE;  
EXCEPTION 
    WHEN EXPRESSION_IS_OF_WRONG_TYPE THEN 
     EXECUTE IMMEDIATE 'BEGIN :ret := '||str||'; END;' USING OUT ds; 
     RETURN TRUE;  
END DailyPartition; 


PROCEDURE RenamePartitions IS 

    ts TIMESTAMP; 
    newName VARCHAR2(30); 

    CURSOR TabPartitions IS 
    SELECT TABLE_NAME, PARTITION_NAME, HIGH_VALUE 
    FROM USER_TAB_PARTITIONS 
    WHERE TABLE_NAME IN ('YOUR_TABLE', ...) 
     AND PARTITION_NAME <> 'P_INITIAL' 
    ORDER BY 1,2; 

BEGIN 

    EXECUTE IMMEDIATE 'ALTER SESSION SET DDL_LOCK_TIMEOUT = 180'; 

    FOR aPart IN TabPartitions LOOP 
     EXECUTE IMMEDIATE 'BEGIN :ret := '||aPart.HIGH_VALUE||'; END;' USING OUT ts; 
     IF DailyPartition(aPart.TABLE_NAME) THEN    
      ts := ts - INTERVAL '1' DAY; 
      newName := 'P_'||TO_CHAR(ts,'yyyy_mm_dd'); 
     ELSE 
      ts := ADD_MONTHS(ts, -1); 
      newName := 'P_'||TO_CHAR(ts,'yyyy_mm'); 
     END IF; 
     IF aPart.PARTITION_NAME <> newName THEN    
      EXECUTE IMMEDIATE 'ALTER TABLE '||aPart.TABLE_NAME||' RENAME PARTITION '||aPart.PARTITION_NAME||' TO '||newName; 
     END IF; 
    END LOOP; 

END RenamePartitions; 
Смежные вопросы