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