Overview

If you plan to add a large quantity of data to a partitioned table, you can use the ALTER TABLE...EXCHANGE PARTITION command to transfer a bulk load of data. You can also use the ALTER TABLE...EXCHANGE PARTITION command to remove outdated or redundant data from storage.

The ALTER TABLE...EXCHANGE PARTITION command has two forms.
  • The first form swaps a table for a partition:
    ALTER TABLE target_table 
    EXCHANGE PARTITION target_partition
    WITH TABLE source_table
    [(WITH | WITHOUT) VALIDATION];
  • The second form swaps a table for a subpartition:
    ALTER TABLE target_table 
    EXCHANGE SUBPARTITION target_subpartition
    WITH TABLE source_table
    [(WITH | WITHOUT) VALIDATION];
The ALTER TABLE...EXCHANGE PARTITION command makes no distinctions between a partition and a subpartition:
  • You can exchange a partition by using the EXCHANGE PARTITION or EXCHANGE SUBPARTITION clause.
  • You can exchange a subpartition by using EXCHANGE PARTITION or EXCHANGE SUBPARTITION clause.

Description

When the ALTER TABLE...EXCHANGE PARTITION command completes, the data is swapped. The data that originally resides in the target partition resides in the source table, and the data that originally resides in the source table resides in the target partition.

The structure of the source table must match the structure of the target table (both tables must have matching columns and data types). The data contained within the table must adhere to the partitioning constraints.

PolarDB-O accepts the WITHOUT VALIDATION clause, but ignores it. The new table is always validated.

You must own a table to call ALTER TABLE...EXCHANGE PARTITION or ALTER TABLE...EXCHANGE SUBPARTITION against that table.

Parameters

ParameterDescription
target_tableThe name (optionally schema-qualified) of the table in which the partition resides.
target_partitionThe name of the partition or subpartition to be replaced.
source_tableThe name of the table that will replace the target_partition.

Example - exchange a table for a partition

The following example demonstrates exchanging a table for a partition (americas) of the sales table. You can run the following command to create the sales table:
CREATE TABLE sales
(
dept_no number,
part_no varchar2,
country varchar2(20),
date date,
amount number
)
PARTITION BY LIST(country)
(
PARTITION europe VALUES('FRANCE', 'ITALY'),
PARTITION asia VALUES('INDIA', 'PAKISTAN'),
PARTITION americas VALUES('US', 'CANADA')
);
Run the following command to add sample data to the sales table:
INSERT INTO sales VALUES
(40, '9519b', 'US', '12-Apr-2012', '145000'),
(10, '4519b', 'FRANCE', '17-Jan-2012', '45000'),
(20, '3788a', 'INDIA', '01-Mar-2012', '75000'),
(20, '3788a', 'PAKISTAN', '04-Jun-2012', '37500'),
(10, '9519b', 'ITALY', '07-Jul-2012', '15000'),
(10, '9519a', 'FRANCE', '18-Aug-2012', '650000'),
(10, '9519b', 'FRANCE', '18-Aug-2012', '650000'),
(20, '3788b', 'INDIA', '21-Sept-2012', '5090'),
(20, '4519a', 'INDIA', '18-Oct-2012', '650000'),
(20, '4519b', 'INDIA', '2-Dec-2012', '5090');
Querying the sales table shows that only one row resides in the americas partition:
acctg=# SELECT tableoid::regclass, * FROM sales;
tableoid | dept_no| part_no | country | date | amount
---------------+--------+---------+---------+-------------------+-----------
sales_europe |
10| 4519b | FRANCE | 17-JAN-12 00:00:00| 45000
sales_europe | 10| 9519b | ITALY | 07-JUL-12 00:00:00| 15000
sales_europe |
10| 9519a | FRANCE | 18-AUG-12 00:00:00| 650000
sales_europe | 10| 9519b | FRANCE | 18-AUG-12 00:00:00| 650000
sales_asia |
20| 3788a | INDIA | 01-MAR-12 00:00:00| 75000
sales_asia | 20| 3788a | PAKISTAN| 04-JUN-12 00:00:00| 37500
sales_asia |
20| 3788b | INDIA | 21-SEP-12 00:00:00| 5090
sales_asia | 20| 4519a | INDIA | 18-OCT-12 00:00:00| 650000
sales_asia |
20| 4519b | INDIA | 02-DEC-12 00:00:00| 5090
sales_americas| 40| 9519b | US | 12-APR-12 00:00:00| 145000
(10 rows)
The following command creates a table (n_america) that matches the definition of the sales table:
CREATE TABLE n_america
(
dept_no number,
part_no varchar2,
country varchar2(20),
date date,
amount number
);
The following command adds data to the n_america table. The data conforms to the partitioning rules of the americas partition:
INSERT INTO n_america VALUES
(40, '9519b', 'US', '12-Apr-2012', '145000'),
(40, '4577b', 'US', '11-Nov-2012', '25000'),
(30, '7588b', 'CANADA', '14-Dec-2012', '50000'),
(30, '9519b', 'CANADA', '01-Feb-2012', '75000'),
(30, '4519b', 'CANADA', '08-Apr-2012', '120000'),
(40, '3788a', 'US', '12-May-2012', '4950'),
(40, '4788a', 'US', '23-Sept-2012', '4950'),
(40, '4788b', 'US', '09-Oct-2012', '15000');
The following command swaps the table into the partitioned table:
ALTER TABLE sales 
EXCHANGE PARTITION americas
WITH TABLE n_america;
Querying the sales table shows that the content of the n_america table has been exchanged for the content of the americas partition:
acctg=# SELECT tableoid::regclass, * FROM sales;
tableoid | dept_no| part_no | country | date | amount
---------------+--------+--------+----------+--------------------+-----------
sales_europe |
10| 4519b | FRANCE | 17-JAN-12 00:00:00 | 45000
sales_europe | 10| 9519b | ITALY | 07-JUL-12 00:00:00 | 15000
sales_europe |
10| 9519a | FRANCE | 18-AUG-12 00:00:00 | 650000
sales_europe | 10| 9519b | FRANCE | 18-AUG-12 00:00:00 | 650000
sales_asia |
20| 3788a | INDIA | 01-MAR-12 00:00:00 | 75000
sales_asia | 20| 3788a | PAKISTAN| 04-JUN-12 00:00:00 | 37500
sales_asia |
20| 3788b | INDIA | 21-SEP-12 00:00:00 | 5090
sales_asia | 20| 4519a | INDIA | 18-OCT-12 00:00:00 | 650000
sales_asia |
20| 4519b | INDIA | 02-DEC-12 00:00:00 | 5090
sales_americas| 40| 9519b | US | 12-APR-12 00:00:00 | 145000
sales_americas|
40| 4577b | US | 11-NOV-12 00:00:00 | 25000
sales_americas| 30| 7588b | CANADA | 14-DEC-12 00:00:00 | 50000
sales_americas|
30| 9519b | CANADA | 01-FEB-12 00:00:00 | 75000
sales_americas| 30| 4519b | CANADA | 08-APR-12 00:00:00 | 120000
sales_americas|
40| 3788a | US | 12-MAY-12 00:00:00 | 4950
sales_americas| 40| 4788a | US | 23-SEP-12 00:00:00 | 4950
sales_americas|
40| 4788b | US | 09-OCT-12 00:00:00 | 15000
(17 rows)
Querying the n_america table shows that the row that was previously stored in the americas partition has been moved to the n_america table:
acctg=# SELECT tableoid::regclass, * FROM n_america;
tableoid | dept_no | part_no | country | date | amount
-----------+---------+---------+---------+--------------------+------------
n_america |
40 | 9519b | US | 12-APR-12 00:00:00 | 145000
(1 row)