Oracle 有没有办法动态创建一个表和一些初始分区?

Oracle 有没有办法动态创建一个表和一些初始分区?,oracle,Oracle,我需要在ORACLE上创建一个包含24个分区的表,从当前时间开始,每天每小时一个分区。 因此,下面的脚本将取决于DBA运行它的时间和日期。 考虑到当前时间和日期,如何提供一个动态脚本来创建表和分区 DROP TABLE TABLE_NAME CASCADE CONSTRAINTS; CREATE TABLE TABLE_NAME ( CODE1 NUMBER(9) DEFAULT ( 0 ), CODE2 NUMBER

我需要在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;

通过基于sysdate构建SQL语句,您可以尝试使用一些动态SQL:

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;

如果您需要每天创建表/分区,那么您可能需要重新考虑您的设计。为什么不使用间隔分区?@WernfriedDomscheit真的不知道为什么。。。这将是一个很好的方法。。。我猜是因为他们只想保留几个分区,因为一个小表是用一个非常大的表的触发器创建的?在去掉q并双引号默认值“”后,我在第45 00900行得到:ORA-00900:无效的SQL语句ORA-06512:。00000-无效的SQL语句这是第45行:执行立即vSQL;q运算符用于避免字符串中的双引号,请参见示例。但是,我的回答中有一个错误,fixedHey@Aleksej,这次我不得不在Oracle 10g上使用类似的动态SQL,而Listag不起作用。我可以在10g上使用什么?在10g中,您可以尝试使用WM_CONCAT,但它没有文档记录,因此可能存在风险;我永远不会在生产数据库中使用它。在这种情况下,可能最简单的事情是一个简单的循环1..24来连接分区字符串。