2016-03-31 2 views
2

Мне нужно создать таблицу на ORACLE с 24 разделами, по одному для каждого часа дня, начиная с текущего времени. Таким образом, следующий сценарий будет зависеть от времени и даты, которые DBA собирается запустить. Как я могу предоставить динамический скрипт, который создает таблицу и разделы с учетом текущего времени и даты?Есть ли способ создать таблицу и некоторые начальные разделы динамически?

DROP TABLE TABLE_NAME CASCADE CONSTRAINTS; 
CREATE TABLE TABLE_NAME 
(
    CODE1    NUMBER(9)   DEFAULT (0), 
    CODE2    NUMBER(9)   DEFAULT (0), 
    CODE3    VARCHAR2(50 BYTE) DEFAULT (' '), 
    VELOCITY   NUMBER(10,3)  DEFAULT (0), 
    REALDATE   TIMESTAMP(6), 
    LOCATION   NUMBER(7,3)   DEFAULT (0), 
    VALIDLOCATION  NUMBER(1)   DEFAULT (0), 
    STARTTIME   NUMBER(9)   DEFAULT (0), 
    OUTBOUND   NUMBER(1)   DEFAULT (0), 
    SERVICE_NAME  VARCHAR2(20 BYTE) DEFAULT (' '), 
    LOCATIONCODE  NUMBER(3)   DEFAULT 0, 
    STARTDATE   TIMESTAMP(6), 
    CODE4    VARCHAR2(1 BYTE) 
) 
NOCOMPRESS 
TABLESPACE TABLESPACE_NAME 
PCTUSED 40 
PCTFREE 10 
INITRANS 1 
MAXTRANS 255 
STORAGE (
      BUFFER_POOL  DEFAULT 
      ) 
PARTITION BY RANGE (REALDATE) 
( 
    PARTITION TABLE_NAME_2016031612 VALUES LESS THAN (TIMESTAMP' 2016-03-16 13:00:00'), 
    PARTITION TABLE_NAME_2016031613 VALUES LESS THAN (TIMESTAMP' 2016-03-16 14:00:00'), 
    PARTITION TABLE_NAME_2016031614 VALUES LESS THAN (TIMESTAMP' 2016-03-16 15:00:00'), 
    PARTITION TABLE_NAME_2016031615 VALUES LESS THAN (TIMESTAMP' 2016-03-16 16:00:00'), 
    PARTITION TABLE_NAME_2016031616 VALUES LESS THAN (TIMESTAMP' 2016-03-16 17:00:00'), 
    PARTITION TABLE_NAME_2016031617 VALUES LESS THAN (TIMESTAMP' 2016-03-16 18:00:00'), 
    PARTITION TABLE_NAME_2016031618 VALUES LESS THAN (TIMESTAMP' 2016-03-16 19:00:00'), 
    PARTITION TABLE_NAME_2016031619 VALUES LESS THAN (TIMESTAMP' 2016-03-16 20:00:00'), 
    PARTITION TABLE_NAME_2016031620 VALUES LESS THAN (TIMESTAMP' 2016-03-16 21:00:00'), 
    PARTITION TABLE_NAME_2016031621 VALUES LESS THAN (TIMESTAMP' 2016-03-16 22:00:00'), 
    PARTITION TABLE_NAME_2016031622 VALUES LESS THAN (TIMESTAMP' 2016-03-16 23:00:00'), 
    PARTITION TABLE_NAME_2016031623 VALUES LESS THAN (TIMESTAMP' 2016-03-17 00:00:00'), 
    PARTITION TABLE_NAME_2016031700 VALUES LESS THAN (TIMESTAMP' 2016-03-17 01:00:00'), 
    PARTITION TABLE_NAME_2016031701 VALUES LESS THAN (TIMESTAMP' 2016-03-17 02:00:00'), 
    PARTITION TABLE_NAME_2016031702 VALUES LESS THAN (TIMESTAMP' 2016-03-17 03:00:00'), 
    PARTITION TABLE_NAME_2016031703 VALUES LESS THAN (TIMESTAMP' 2016-03-17 04:00:00'), 
    PARTITION TABLE_NAME_2016031704 VALUES LESS THAN (TIMESTAMP' 2016-03-17 05:00:00'), 
    PARTITION TABLE_NAME_2016031705 VALUES LESS THAN (TIMESTAMP' 2016-03-17 06:00:00'), 
    PARTITION TABLE_NAME_2016031706 VALUES LESS THAN (TIMESTAMP' 2016-03-17 07:00:00'), 
    PARTITION TABLE_NAME_2016031707 VALUES LESS THAN (TIMESTAMP' 2016-03-17 08:00:00'), 
    PARTITION TABLE_NAME_2016031708 VALUES LESS THAN (TIMESTAMP' 2016-03-17 09:00:00'), 
    PARTITION TABLE_NAME_2016031709 VALUES LESS THAN (TIMESTAMP' 2016-03-17 10:00:00'), 
    PARTITION TABLE_NAME_2016031710 VALUES LESS THAN (TIMESTAMP' 2016-03-17 11:00:00'), 
    PARTITION TABLE_NAME_2016031711 VALUES LESS THAN (TIMESTAMP' 2016-03-17 12:00:00') 
) 
NOCACHE 
NOPARALLEL 
MONITORING; 
+2

Если вам нужно создавать таблицы/разделы каждый день, то вы можете повторно рассмотреть ваш дизайн. – OldProgrammer

+1

Почему вы не используете раздел 'INTERVAL'? –

+0

@WernfriedDomscheit действительно не знает, почему ... был бы хороший подход ... Я думаю, это потому, что они хотят сохранить только несколько разделов, поскольку это маленькая таблица, которая создается с помощью триггера из очень большой таблицы. – Rodrick

ответ

4

Вы можете попробовать с каким-то динамическим SQL, путем построения SQL заявления на основе SYSDATE:

declare 
    vSQL   varchar2(32767); 
    vPartitions  varchar2(32767); 
begin 
    select listagg('PARTITION TABLE_NAME_' || to_char(sysdate + level/24, 'yyyymmddhh24') || 
        ' VALUES LESS THAN (TIMESTAMP''' || to_char(sysdate + (level+1)/24, 'yyyy-mm-dd hh24') || ':00:00'')' 
        , ', ') within group (order by level) 
    into vPartitions 
    from dual 
    connect by level <= 24; 
    -- 
    vSQL := q'[ CREATE TABLE TABLE_NAME 
       (
        CODE1    NUMBER(9)   DEFAULT (0), 
        CODE2    NUMBER(9)   DEFAULT (0), 
        CODE3    VARCHAR2(50 BYTE) DEFAULT (' '), 
        VELOCITY   NUMBER(10,3)  DEFAULT (0), 
        REALDATE   TIMESTAMP(6), 
        LOCATION   NUMBER(7,3)   DEFAULT (0), 
        VALIDLOCATION  NUMBER(1)   DEFAULT (0), 
        STARTTIME   NUMBER(9)   DEFAULT (0), 
        OUTBOUND   NUMBER(1)   DEFAULT (0), 
        SERVICE_NAME  VARCHAR2(20 BYTE) DEFAULT (' '), 
        LOCATIONCODE  NUMBER(3)   DEFAULT 0, 
        STARTDATE   TIMESTAMP(6), 
        CODE4    VARCHAR2(1 BYTE) 
       ) 
       NOCOMPRESS 
       TABLESPACE TABLESPACE_NAME 
       PCTUSED 40 
       PCTFREE 10 
       INITRANS 1 
       MAXTRANS 255 
       STORAGE (
          BUFFER_POOL  DEFAULT 
          ) 
       PARTITION BY RANGE (REALDATE) 
       (]' || vPartitions || 
       ') 
       NOCACHE 
       NOPARALLEL 
       MONITORING';  
    execute immediate 'DROP TABLE TABLE_NAME CASCADE CONSTRAINTS'; 
    execute immediate vSQL; 
end; 
+0

Что такое «q» на «vSQL: = q»? После вынимания "д" и дважды квотирования DEFAULT ('') я получаю: ORA-00900: недопустимое заявление SQL ORA-06512: в строке 45 00900. 00000 - "недопустимое заявление SQL" Это строка 45: выполнить немедленный vSQL; – Rodrick

+0

Оператор q используется, чтобы избежать двойного кавычки в строке (см. Здесь [здесь] (http://www.oracle-developer.net/display.php?id=311)). Однако в моем ответе была ошибка, исправлено – Aleksej

+0

Большое вам спасибо! :) – Rodrick

Смежные вопросы