oracle partition by group_id and subpartition monthly - oracle

I want to create a table like this.
create table some_data (
id number(19,0),
group_id number(19,0),
value float,
timestamp timestamp
);
For this table i would like to have the data stored like
group_id=1
jan-2015
feb-2015
...
group_id=2
jan-2015
feb-2015
...
and so on. So I assume i have to create a partition by range for the group_id and then a subpartition also by range with the timestamp column, right?
So it should look like this:
create table some_data (
id number(19,0),
group_id number(19,0),
value float,
timestamp timestamp
)
PARTITION BY RANGE (group_id)
SUBPARTITION BY RANGE ("TIMESTAMP")
INTERVAL (NUMTOYMINTERVAL(1,'MONTH'))
(
PARTITION part_1 values LESS THAN (TO_DATE('01.02.2015','DD.MM.YYYY'))
);
Is this right? And also the question: With this partition, if a new group_id is added, will oracle create automatically a new partition for the new group_id and the new suppartitions for new data with new months?

Interval partitioning is not supported on subpartition level:
http://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_7002.htm#SQLRF54559
You can define it like this:
create table some_data (
id number(19,0),
group_id number(19,0),
value float,
timestamp timestamp -- not good naming
)
PARTITION BY RANGE ("TIMESTAMP")
INTERVAL (NUMTOYMINTERVAL(1,'MONTH'))
SUBPARTITION BY RANGE (group_id) -- it could be hash or list as well
subpartition template(
...
)
(
PARTITION part_1 values LESS THAN (TO_DATE('01.02.2015','DD.MM.YYYY'))
);

Related

Problem with alter table big_table modify partition

I create table:
create table big_table(
bt_id number primary key,
bt_date date,
bt_value varchar2(20)
)
Then I wnat partition this table (code abbreviated):
alter table big_table modify
partition by range (bt_date)
interval(numtoyminterval(1, 'MONTH'))
subpartition by hash (bt_id)
(
partition nn_st_p1 values less than (to_date(' 2019-05-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
subpartitions 4
store in (ipr_tbl),
)online
Error message:
17:20:39 line 1: ORA-14006: invalid partition name
I can't understand what is wrong with my partition name?
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
Try something like this
CREATE TABLE big_table
(bt_id NUMBER PRIMARY KEY
, bt_date DATE
, bt_value VARCHAR2(20)
)
PARTITION BY RANGE (bt_date) INTERVAL (NUMTOYMINTERVAL(1,'MONTH'))
SUBPARTITION BY HASH (bt_id) SUBPARTITIONS 4
(PARTITION nn_st_p1 VALUES LESS THAN (TO_DATE('01-MAY-2019','dd-MON-yyyy'))
)
PARALLEL;

Oracle - Error on EXCHANGE PARTITION with List-Range partitioning

I'm trying to use EXCHANGE PARTITION on following example schema:
CREATE TABLE TEMP_TABLE_00(
CONTACT_ID NUMBER,
SECONDARY_CONTACT_FLAG NUMBER,
SOURCE_SYSTEM VARCHAR2(10 CHAR),
START_DATE DATE,
ACTIVE NUMBER,
SECONDARY_CONTACT_FLAGS NUMBER GENERATED ALWAYS AS (ACTIVE || SECONDARY_CONTACT_FLAG) VIRTUAL,
CONSTRAINT pk_temp_table_00 PRIMARY KEY (CONTACT_ID))
PARTITION BY LIST (SECONDARY_CONTACT_FLAGS)
SUBPARTITION BY RANGE (START_DATE)
( PARTITION p_ac_00 VALUES ('00')
( SUBPARTITION sp_ac_00_before_2014 VALUES LESS THAN (TO_DATE ('01.01.2014', 'DD.MM.YYYY')),
SUBPARTITION sp_ac_00_201401 VALUES LESS THAN (TO_DATE ('01.02.2014', 'DD.MM.YYYY'))
)
)
ENABLE ROW MOVEMENT;
create table TARGET_TABLE(
CONTACT_ID NUMBER,
SECONDARY_CONTACT_FLAG NUMBER,
SOURCE_SYSTEM VARCHAR2(10 CHAR),
START_DATE DATE,
ACTIVE NUMBER,
SECONDARY_CONTACT_FLAGS NUMBER GENERATED ALWAYS AS (ACTIVE || SECONDARY_CONTACT_FLAG) VIRTUAL,
CONSTRAINT pk_target_table PRIMARY KEY (CONTACT_ID))
PARTITION BY LIST (secondary_contact_flags)
SUBPARTITION BY RANGE (START_DATE)
( PARTITION p_ac_00 VALUES ('00')
( SUBPARTITION sp_ac_00_before_2014 VALUES LESS THAN (TO_DATE ('01.01.2014', 'DD.MM.YYYY')),
SUBPARTITION sp_ac_00_201401 VALUES LESS THAN (TO_DATE ('01.02.2014', 'DD.MM.YYYY'))
),
PARTITION p_ac_10 VALUES ('10')
( SUBPARTITION sp_ac_10_before_2014 VALUES LESS THAN (TO_DATE ('01.01.2014', 'DD.MM.YYYY')),
SUBPARTITION sp_ac_10_201401 VALUES LESS THAN (TO_DATE ('01.02.2014', 'DD.MM.YYYY'))
),
PARTITION p_ac_01 VALUES ('01')
( SUBPARTITION sp_ac_01_before_2014 VALUES LESS THAN (TO_DATE ('01.01.2014', 'DD.MM.YYYY')),
SUBPARTITION sp_ac_01_201401 VALUES LESS THAN (TO_DATE ('01.02.2014', 'DD.MM.YYYY'))
),
PARTITION p_ac_11 VALUES ('11')
( SUBPARTITION sp_ac_11_before_2014 VALUES LESS THAN (TO_DATE ('01.01.2014', 'DD.MM.YYYY')),
SUBPARTITION sp_ac_11_201401 VALUES LESS THAN (TO_DATE ('01.02.2014', 'DD.MM.YYYY'))
)
)
ENABLE ROW MOVEMENT;
INSERT INTO DM_KSCTSC.TEMP_TABLE_00 (CONTACT_ID, SECONDARY_CONTACT_FLAG, SOURCE_SYSTEM, START_DATE, ACTIVE) VALUES (1, 0, 'ABC', TO_DATE('20140101', 'YYYYMMDD'), 0);
commit;
When trying to exchange partitions:
alter table target_table exchange partition p_ac_00 with table TEMP_TABLE_00 without validation;
even though the structure of the partitions are identical, Oracle returns an
ORA-14292: Partitioning type of table must match subpartitioning type
of composite partition
Is there another solution than exchanging every subpartition seperately?
To be able to exchange partition between a partition table (PT) and a non-partitioned table (TMP) the TMP table must have the same structure as the partition of PT.
I.e. if the PT is partitioned, the TMP is non-partitioned.
If the PT is composit partitioned, the TMP is partitioned in the same way as the subpartition of PT.
In your case is the problem in the TMP table (TEMP_TABLE_00), it must be partitioned by RANGE (same as the subpartition of TARGET_TABLE)
CREATE TABLE TEMP_TABLE_00(
CONTACT_ID NUMBER,
SECONDARY_CONTACT_FLAG NUMBER,
SOURCE_SYSTEM VARCHAR2(10 CHAR),
START_DATE DATE,
ACTIVE NUMBER,
SECONDARY_CONTACT_FLAGS NUMBER GENERATED ALWAYS AS (ACTIVE || SECONDARY_CONTACT_FLAG) VIRTUAL,
CONSTRAINT pk_temp_table_00 PRIMARY KEY (CONTACT_ID))
PARTITION BY RANGE (START_DATE)
( PARTITION sp_ac_00_before_2014 VALUES LESS THAN (TO_DATE ('01.01.2014', 'DD.MM.YYYY')),
PARTITION sp_ac_00_201401 VALUES LESS THAN (TO_DATE ('01.02.2014', 'DD.MM.YYYY'))
)
ENABLE ROW MOVEMENT;
In this setup the exchange partition works.

Tablespaces with interval partitioning

Is there any way to specify different tablespaces for each partition if I use interval partitioning?
My table is (it is just example, I have more columns in the table):
create table MY_TABLE
(
id NUMBER(20) not null,
type VARCHAR2(1 char) not null,
session_id NUMBER(12) not null,
date_of_beginning DATE not null,
account_number NUMBER not null
)
PCTFREE 1
PARTITION BY RANGE (date_of_beginning)
INTERVAL(NUMTOYMINTERVAL(1, ''MONTH''))
SUBPARTITION BY HASH(account_number) subpartitions 50
(
PARTITION p_1 VALUES LESS THAN (TO_DATE(''01.06.2015'', ''dd.mm.yyyy''))
)';
I want each partition to be stored in separate tablespase. Any ideas how can I achieve it? Maybe some trigger?
For other tables like this one, we have a job, which creates tablespace and partition in the beginning of the month. But this one creates partitions automatically because of intervals.

How to create Day and Hourly partitioning in Oracle 11g?

I am using Oracle-11G database.
I am trying to create day wise partition and again sub-partition on hourly level.
Below is the script I am using
CREATE TABLE test_shipments
( order_date DATE NOT NULL
, delivery_date DATE NOT NULL
)
PARTITION BY RANGE (order_date)
INTERVAL (NUMTODSINTERVAL(1, 'day'))
SUBPARTITION BY RANGE (order_date)
( PARTITION p_2006_jul VALUES LESS THAN (TO_DATE('2006-08-01','YYYY-MM-DD'))
( SUBPARTITION p06_jul_e1 VALUES LESS THAN (TO_DATE('2006-08-01 12:00:00','YYYY-MM-DD hh24:mi:ss'))
,SUBPARTITION p06_jul_e2 VALUES LESS THAN (TO_DATE('2006-08-01 13:00:00','YYYY-MM-DD hh24:mi:ss'))
,SUBPARTITION p06_jul_e3 VALUES LESS THAN (TO_DATE('2006-08-01 14:00:00','YYYY-MM-DD hh24:mi:ss'))
)
);
I am expecting to have partition for every day and again sub-partition for every hour in that day. The above script creates partition per day only. Hourly sub-partition is not getting created. Can anyone please guide?
Why do you not create simple partition by Hourly range? Example: PARTITION BY RANGE (order_date) INTERVAL (INTERVAL '1' HOUR)
Anyway, this one works. However, you should use TIMESTAMP data type instead of DATE. For hour value you have to create a virtual column.
CREATE TABLE test_shipments (
order_date TIMESTAMP(0) NOT NULL,
order_date_hour NUMBER GENERATED ALWAYS AS (EXTRACT(HOUR FROM order_date)),
delivery_date DATE NOT NULL)
PARTITION BY RANGE (order_date)
INTERVAL (INTERVAL '1' DAY)
SUBPARTITION BY LIST (order_date_hour)
SUBPARTITION TEMPLATE
(SUBPARTITION HOUR00 VALUES (0),
SUBPARTITION HOUR01 VALUES (1),
SUBPARTITION HOUR02 VALUES (2),
SUBPARTITION HOUR03 VALUES (3),
...
SUBPARTITION HOUR22 VALUES (22),
SUBPARTITION HOUR23 VALUES (23)
)
(
PARTITION P_20150101 VALUES LESS THAN (TIMESTAMP'2015-01-01 00:00:00')
);
If you are enforced to use DATE data type you can do it like this:
CREATE TABLE test_shipments (
order_date DATE NOT NULL,
order_date_hour NUMBER GENERATED ALWAYS AS (TO_CHAR(order_date, 'HH24')),
delivery_date DATE NOT NULL)
PARTITION BY RANGE (order_date)
INTERVAL (INTERVAL '1' DAY)
SUBPARTITION BY LIST (order_date_hour)
SUBPARTITION TEMPLATE
(SUBPARTITION HOUR00 VALUES (0),
SUBPARTITION HOUR01 VALUES (1),
SUBPARTITION HOUR02 VALUES (2),
SUBPARTITION HOUR03 VALUES (3),
...
SUBPARTITION HOUR22 VALUES (22),
SUBPARTITION HOUR23 VALUES (23)
)
(
PARTITION P_20150101 VALUES LESS THAN (DATE '2015-01-01')
);
Maybe you want to group night time hours:
(
SUBPARTITION HOUR_NIGHT VALUES (0,1,2,3,4,5,6, 19,20,21,22,23),
SUBPARTITION HOUR07 VALUES (7),
SUBPARTITION HOUR08 VALUES (8),
SUBPARTITION HOUR11 VALUES (11),
...
SUBPARTITION HOUR17 VALUES (17),
SUBPARTITION HOUR18 VALUES (18)
)

How do I create a partitioned table without initial partitions?

Say, I have the following DDL:
create table partition_test_table
(
id number(38,0) not null,
value varchar(255),
country_code varchar(2) not null,
creation_date date not null,
constraint pk_partition_test_table primary key (id)
)
partition by range ( creation_date )
subpartition by list ( country_code );
This doesn't work because it doesn't declare any initial partitions. How do I create a partitioned table without initial partitions? Is that even possible?
Thanks.

Resources