Purpose
This statement is used to modify the structure of an existing table, including modifying the table name and table attributes, adding columns, modifying the column name and attributes, and dropping columns.
Syntax
ALTER TABLE table_name alter_table_actions;
| ALTER TABLE EXTERNAL table_name alter_table_actions;
| ALTER TABLE table_name alter_column_group_option;
| ALTER TABLE EXTERNAL table_name ADD PARTITION '(' add_external_table_partition_actions ')' LOCATION STRING_VALUE;
| ALTER TABLE EXTERNAL table_name DROP PARTITION LOCATION STRING_VALUE;
alter_table_actions:
alter_table_action
| alter_table_actions ',' alter_table_action
| exclude_alter_table_action
exclude_alter_table_action:
alter_partition_option
| modify_partition_info
| auto_split_range_partition_option
alter_table_action:
table_option_list_space_seperated
| SET table_option_list_space_seperated
| opt_alter_compress_option
| alter_column_option
| alter_tablegroup_option
| RENAME relation_factor
| RENAME TO relation_factor
| alter_index_option
| DROP CONSTRAINT constraint_name
| enable_option ALL TRIGGERS
| REFRESH
| enable_macro_block_bloom_filter
| DYNAMIC_PARTITION_POLICY [=] (dynamic_partition_policy_list)
dynamic_partition_policy_list:
dynamic_partition_policy_option [, dynamic_partition_policy_option ...]
dynamic_partition_policy_option:
ENABLE = {true | false}
| PRECREATE_TIME = {'-1' | '0' | 'n {hour | day | week | month | year}'}
| EXPIRE_TIME = {'-1' | '0' | 'n {hour | day | week | month | year}'}
alter_partition_option:
DROP PARTITION drop_partition_name_list
| DROP PARTITION drop_partition_name_list UPDATE GLOBAL INDEXES
| RENAME PARTITION relation_name TO relation_name
| add_range_or_list_partition
| SPLIT PARTITION relation_factor split_actions
| TRUNCATE PARTITION name_list
| TRUNCATE PARTITION name_list UPDATE GLOBAL INDEXES
| MODIFY PARTITION relation_factor add_range_or_list_subpartition
| RENAME SUBPARTITION relation_name TO relation_name
| DROP SUBPARTITION drop_partition_name_list
| DROP SUBPARTITION drop_partition_name_list UPDATE GLOBAL INDEXES
| TRUNCATE SUBPARTITION name_list
| TRUNCATE SUBPARTITION name_list UPDATE GLOBAL INDEXES
| EXCHANGE {PARTITION partition_name
| SUBPARTITION subpartition_name} WITH TABLE origin_table_name INCLUDING INDEXES WITHOUT VALIDATION
alter_column_group_option:
ADD COLUMN GROUP '(' column_group_list ')' alter_column_group_delayed_desc
| DROP COLUMN GROUP '(' column_group_list ')' alter_column_group_delayed_desc
modify_partition_info:
MODIFY hash_partition_option
| MODIFY list_partition_option
| MODIFY range_partition_option
auto_split_range_partition_option:
PARTITION BY RANGE '(' ')' opt_auto_split_tablet_size_option
| PARTITION BY RANGE '(' column_name_list ')' subpartition_option opt_auto_split_range_partition_info
| MODIFY PARTITION BY RANGE '(' ')' opt_auto_split_tablet_size_option
| MODIFY PARTITION BY RANGE '(' column_name_list ')' subpartition_option auto_split_tablet_size_option
| MODIFY PARTITION BY RANGE '(' column_name_list ')' subpartition_option auto_split_tablet_size_option opt_range_partition_list
add_external_table_partition_actions:
add_external_table_partition_action
| add_external_table_partition_actions ',' add_external_table_partition_action
| /* empty */
opt_auto_split_tablet_size_option:
| AUTO_SPLIT_TABLET_SIZE '(' integer_value ')'
| /* empty */
Syntax
| Parameter | Description |
|---|---|
ALTER TABLE table_name alter_table_actions |
Modifies a regular table. |
ALTER TABLE EXTERNAL table_name alter_table_actions |
Modifies an external table. |
ALTER TABLE table_name alter_column_group_option |
Modifies a column group. |
ALTER TABLE EXTERNAL table_name ADD PARTITION (...) LOCATION STRING_VALUE |
Adds a partition to an external table. |
ALTER TABLE EXTERNAL table_name DROP PARTITION LOCATION STRING_VALUE |
Drops a partition from an external table. |
table_option_list_space_seperated |
Sets various options of a table. |
SET table_option_list_space_seperated |
Sets table options by using a SET statement. |
opt_alter_compress_option |
Modifies the compression options of a table. |
alter_column_option |
Modifies a column definition. |
alter_tablegroup_option |
Modifies table group options. |
RENAME relation_factor |
Renames a table. |
DROP CONSTRAINT constraint_name |
Drops a constraint. |
REFRESH |
Refreshes a table. |
enable_macro_block_bloom_filter |
Specifies whether to persist the macro block-level bloom filter. The values are as follows:
NoteFor OceanBase Database V4.3.5, the |
DROP PARTITION partition_name |
Drops a specified partition. |
RENAME PARTITION old_name TO new_name |
Renames a partition. This statement renames a partition or subpartition. The new_name parameter is case-insensitive and specifies the new name of the partition to be modified. This operation modifies the name of the corresponding partition in the primary table but does not affect the partition names in local indexes. You can query the USER_TAB_PARTITIONS or USER_TAB_SUBPARTITIONS view to confirm the new partition name. For more information, see Rename a partition. The renaming operation is blocked if it conflicts with a DML operation that holds resources required for the partition lock during the renaming operation. |
SPLIT PARTITION partition_name split_actions |
Splits a partition. You can use the split_at_format or split_into_format format to manually split a partition. For more information, see split_partition_option. |
TRUNCATE PARTITION partition_name |
Truncates data in a partition. |
MODIFY PARTITION partition_name ... |
Modifies partition attributes. This statement adds subpartitions.
NoticeDo not use this statement to add a subpartition of the HASH type. |
ADD COLUMN GROUP (column_list) [DELAYED] |
Adds a column group. This changes a table into a column store table. Specific explanations are as follows:
|
DROP COLUMN GROUP (column_list) [DELAYED] |
Drops a column group. This removes the storage format of a table. Specific explanations are as follows:
|
MODIFY hash_partition_option |
Modifies a hash partition. |
MODIFY list_partition_option |
Modifies a list partition. |
MODIFY range_partition_option |
Modifies a range partition. |
PARTITION BY RANGE (...) opt_auto_split_tablet_size_option |
Enables automatic partition splitting for RANGE partitions. |
AUTO_SPLIT_TABLET_SIZE (size) |
Sets the size threshold for splitting RANGE partitions. |
add_external_table_partition_action |
Defines the attributes of an external table partition. |
add_external_table_partition_actions ',' action |
Defines multiple partitions for an external table. |
ADD |
Adds a column. Currently, you cannot add a primary key column by using this option. |
MODIFY COLUMN |
Modifies a column attribute. |
MODIFY CONSTRAINT |
Modifies the status of a constraint to enabled or disabled. Only foreign key constraints and CHECK constraints are supported. |
DROP PRIMARY KEY |
Drops a primary key.
NoteIn Oracle compatible mode, you cannot drop a primary key for a table that is a parent table of foreign key information. |
EXCHANGE {PARTITION partition_name \| SUBPARTITION subpartition_name} WITH TABLE origin_table_name INCLUDING INDEXES WITHOUT VALIDATION |
Specifies the partition exchange. Details:
|
| DYNAMIC_PARTITION_POLICY [=] (dynamic_partition_policy_list) | Modifies the dynamic partition management attribute of a table. dynamic_partition_policy_list is a list of parameters that specify the dynamic partitioning strategy for the table. The parameters are separated with commas. For more information, see dynamic_partition_policy_option.
NoteStarting from V4.3.5 BP2, you can specify the dynamic partition management attribute for a table in OceanBase Database V4.3.5. |
split_partition_option
SPLIT PARTITION partition_name AT (value) [INTO (PARTITION split_partition_name1, PARTITION [split_partition_name2])]: When you split a partition by using this syntax, the system splits the source partition into two partitions based on the givenvalue. You can also use theINTOclause to specify the names of the split partitions.SPLIT PARTITION partition_name INTO (PARTITION split_partition_name VALUES LESS THAN (value) [, PARTITION split_partition_name VALUES LESS THAN (value) ...], PARTITION split_partition_name): When you split a partition by using this syntax, you can split a partition into multiple partitions. Thevaluerange specified for partition splitting must be the same as that of the source partition and thevaluemust be defined in ascending order (the definition of the last partition cannot be left empty, and itsvalueis the same as that of the source partition).
For more information about manual partition splitting, see Manually split a partition.
dynamic_partition_policy_option
ENABLE = {true | false}: specifies whether to enable dynamic partition management. The values are as follows:true: default value, enables dynamic partition management.false: disables dynamic partition management.
PRECREATE_TIME = {'-1' | '0' | 'n {hour | day | week | month | year}'}: the pre-creation time. Each time dynamic partition management is scheduled, partitions will be pre-created so that the upper bound of the largest partition > now() + precreate_time. The values are as follows:-1: default value, no partitions will be pre-created.0: only the current partition will be pre-created.n {hour | day | week | month | year}: partitions will be pre-created for the specified time span. For example,3 hourmeans pre-create partitions for the next 3 hours.
Note
- When multiple partitions need to be pre-created, the interval between partition boundaries is determined by
TIME_UNIT. - The boundary of the first pre-created partition is the smallest multiple of
TIME_UNITthat is greater than or equal to the current maximum partition boundary.
EXPIRE_TIME = {'-1' | '0' | 'n {hour | day | week | month | year}'}: optional. Specifies the partition expiration time. Each time dynamic partition management is scheduled, all partitions with upper bound < now() - expire_time will be deleted as expired partitions. This value can be modified. The values are as follows:-1: default value, partitions never expire.0: all partitions prior to the current partition are considered expired.n {hour | day | week | month | year}: specifies the partition expiration time. For example,1 daymeans the partition expires after 1 day.
For more information about modifying dynamic partitioned tables, see Modify dynamic partitioned tables.
Here is an example:
ALTER TABLE tbl2 SET DYNAMIC_PARTITION_POLICY(
ENABLE = true,
PRECREATE_TIME = '1 day',
EXPIRE_TIME = '-1'
);
Examples
Change the type of the
col1field in thetbl1table.obclient> CREATE TABLE tbl1(col1 VARCHAR(3)); obclient> ALTER TABLE tbl1 MODIFY col1 CHAR(10); obclient> DESCRIBE tbl1;Rename the
col1column in thetbl1table tocol2.obclient> ALTER TABLE tbl1 RENAME COLUMN col1 TO col2; obclient> DESCRIBE tbl1;Add and drop columns.
Create a
tbl2table.obclient> CREATE TABLE tbl2 (col1 NUMBER(30) PRIMARY KEY,col2 VARCHAR(50));Add a column named
col3to thetbl2table.obclient> ALTER TABLE tbl2 ADD col3 NUMBER(30); obclient> DESCRIBE tbl2;Drop the
col3column from thetbl2table.obclient> ALTER TABLE tbl2 DROP COLUMN col3; obclient> DESCRIBE tbl2;Create a unique index on the
tbl2table.obclient> CREATE TABLE tbl2 (col1 NUMBER(30) PRIMARY KEY,col2 VARCHAR(50), col3 INT); obclient> ALTER TABLE tbl2 ADD CONSTRAINT constraint_TBL2 UNIQUE (col2, col3); obclient [SYS]> DESC tbl2; obclient> INSERT INTO tbl2 VALUES('1','2','2'); obclient> INSERT INTO tbl2 VALUES('2','2','2'); obclient> INSERT INTO tbl2 VALUES('2','3','2');
Add a foreign key to the
ref_t2table. When aDELETEoperation affects a row in the parent table that matches a row in the child table, the foreign key constraint performs aSET NULLoperation.obclient> CREATE TABLE ref_t1(c1 INT PRIMARY KEY,C2 INT); obclient> CREATE TABLE ref_t2(c1 INT PRIMARY KEY,C2 INT); obclient> ALTER TABLE ref_t2 ADD CONSTRAINT fk1 FOREIGN KEY (c2) REFERENCES ref_t1(c1) ON DELETE SET NULL;Add a non-template subpartition to the
tbl3table and specify the partitioning key and subpartitioning key of the partition.obclient> ALTER TABLE tbl3 MODIFY PARTITION p1 ADD SUBPARTITION p1_r4 VALUES LESS THAN(2022);Drop a non-template subpartition from the
tbl3table.obclient> ALTER TABLE tbl3 DROP SUBPARTITION p2_r3;Add a partition to the
tbl3table and specify the partitioning key and subpartitioning key of the partition and subpartition.obclient> ALTER TABLE tbl3 ADD PARTITION p4 VALUES LESS THAN (400) ( SUBPARTITION p4_r1 VALUES LESS THAN (2019), SUBPARTITION p4_r2 VALUES LESS THAN (2020), SUBPARTITION p4_r3 VALUES LESS THAN (2021) );Add a partition to the
tbl4table and specify the partitioning key and subpartitioning key of the partition and subpartition.obclient> CREATE TABLE tbl4(col1 INT, col2 INT, PRIMARY KEY(col1,col2)) PARTITION BY RANGE(col1) SUBPARTITION BY RANGE(col2) SUBPARTITION TEMPLATE ( SUBPARTITION p0 VALUES LESS THAN (50), SUBPARTITION p1 VALUES LESS THAN (100) ) ( PARTITION p0 VALUES LESS THAN (100), PARTITION p1 VALUES LESS THAN (200), PARTITION p2 VALUES LESS THAN (300) ); obclient> ALTER TABLE tbl4 ADD PARTITION p3 VALUES LESS THAN (400);Change the parallelism of the
tbl5table to3.obclient> CREATE TABLE tbl5(col1 int primary key, col2 int) PARALLEL 5; obclient> ALTER TABLE tbl5 PARALLEL 3;or:
obclient> CREATE TABLE tbl5(col1 int primary key, col2 int) PARALLEL 5; obclient> ALTER /*+ parallel(3) */ TABLE tbl5;Change the status of the foreign key constraint.
obclient> CREATE TABLE MMS_GROUPUSER ( "ID" VARCHAR2(254 BYTE) NOT NULL, "GROUPID" VARCHAR2(254 BYTE), "USERID" VARCHAR2(254 BYTE), CONSTRAINT "PK_MMS_GROUPUSER" PRIMARY KEY ("ID"), CONSTRAINT "FK_MMS_GROUPUSER_02" FOREIGN KEY ("GROUPID") REFERENCES MMS_GROUPUSER ("ID") ON DELETE CASCADE DISABLE ); obclient> SELECT CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,STATUS FROM user_constraints WHERE CONSTRAINT_NAME LIKE 'FK_MMS_GROUPUSE%'; obclient> ALTER TABLE MMS_GROUPUSER ENABLE CONSTRAINT FK_MMS_GROUPUSER_02; obclient> SELECT CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,STATUS FROM user_constraints WHERE CONSTRAINT_NAME LIKE 'FK_MMS_GROUPUSE%';Clear all data in the
M202001andM202002partitions of the partitioned tabletbl6.obclient> CREATE TABLE tbl6 (log_id number NOT NULL,log_value varchar2(50),log_date date NOT NULL DEFAULT sysdate) PARTITION BY RANGE(log_date) ( PARTITION M202001 VALUES LESS THAN(TO_DATE('2020/02/01','YYYY/MM/DD')) , PARTITION M202002 VALUES LESS THAN(TO_DATE('2020/03/01','YYYY/MM/DD')) , PARTITION M202003 VALUES LESS THAN(TO_DATE('2020/04/01','YYYY/MM/DD')) , PARTITION M202004 VALUES LESS THAN(TO_DATE('2020/05/01','YYYY/MM/DD')) , PARTITION M202005 VALUES LESS THAN(TO_DATE('2020/06/01','YYYY/MM/DD')) , PARTITION MMAX VALUES LESS THAN (MAXVALUE) ); obclient> ALTER TABLE tbl6 TRUNCATE PARTITION M202001, M202002 UPDATE GLOBAL INDEXES;Drop the
CHECKconstraint namedtbl7_equal_check1from thetbl7table.obclient> CREATE TABLE tbl7 (col1 INT, col2 INT, col3 INT,CONSTRAINT tbl7_equal_check1 CHECK(col2 = col3 * 2) ENABLE VALIDATE); obclient> SELECT CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,STATUS FROM user_constraints WHERE TABLE_NAME LIKE 'TBL%'; obclient> ALTER TABLE tbl7 DROP CONSTRAINT tbl7_equal_check1; obclient> SELECT CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,STATUS FROM user_constraints WHERE TABLE_NAME LIKE 'TBL%';Move the
tbl8table from thetblgroup1table group to thetblgroup2table group.obclient> SHOW TABLEGROUPS; obclient> ALTER TABLE tbl8 SET TABLEGROUP tblgroup2; obclient> SHOW TABLEGROUPS;Add a foreign key constraint named
cons_fk1to theprimary_tabletable.obclient> CREATE TABLE primary_table (id NUMBER PRIMARY KEY, names VARCHAR(100) NOT NULL, foreign_col NUMBER); obclient> CREATE TABLE reference_table (id NUMBER PRIMARY key, comments VARCHAR2(100) NOT NULL); obclient> ALTER TABLE primary_table ADD CONSTRAINT cons_fk1 FOREIGN KEY(foreign_col) REFERENCES reference_table(id);Add a primary key constraint named
tbl1_pkto thetbl9table.obclient> CREATE TABLE tbl9 (col1 NUMBER, col2 INT,col3 VARCHAR2(100)); obclient> ALTER TABLE tbl9 ADD CONSTRAINT tbl1_pk PRIMARY KEY (col1);Modify the primary key of the
tbl9table to thecol2field.obclient> ALTER TABLE tbl9 MODIFY PRIMARY KEY(col2);Drop the primary key constraint from the
tbl9table.obclient> ALTER TABLE tbl9 DROP PRIMARY KEY;Rename partitions and subpartitions.
/* Create a subpartitioned table named range_range_table and create a local index on this table based on the col1 column. */ CREATE TABLE range_range_table(col1 INT, col2 INT, col3 INT) PARTITION BY RANGE(col1) SUBPARTITION BY RANGE(col2) (PARTITION p0 VALUES LESS THAN(100) (SUBPARTITION sp0 VALUES LESS THAN(100), SUBPARTITION sp1 VALUES LESS THAN(200) ), PARTITION p1 VALUES LESS THAN(200) (SUBPARTITION sp2 VALUES LESS THAN(100), SUBPARTITION sp3 VALUES LESS THAN(200), SUBPARTITION sp4 VALUES LESS THAN(300) ) ); CREATE INDEX local_idx_for_range_range_tb ON range_range_table (col1) LOCAL; /* Rename a partition without changing the name of the local index partition. */obclient> SELECT partition_name FROM SYS.USER_TAB_PARTITIONS WHERE table_name = 'RANGE_RANGE_TABLE'; obclient> ALTER TABLE range_range_table RENAME PARTITION p0 TO p10; obclient> SELECT partition_name FROM SYS.USER_TAB_PARTITIONS WHERE table_name = 'RANGE_RANGE_TABLE'; obclient> SELECT partition_name FROM SYS.USER_IND_PARTITIONS WHERE index_name = 'LOCAL_IDX_FOR_RANGE_RANGE_TB'; /* Rename a subpartition without changing the name of the local index partition. */ obclient> SELECT partition_name, subpartition_name FROM SYS.USER_TAB_SUBPARTITIONS WHERE table_name = 'RANGE_RANGE_TABLE'; obclient> ALTER TABLE range_range_table RENAME SUBPARTITION sp0 TO sp10; obclient> SELECT partition_name, subpartition_name FROM SYS.USER_TAB_SUBPARTITIONS WHERE table_name = 'RANGE_RANGE_TABLE'; obclient> SELECT partition_name, subpartition_name FROM SYS.USER_IND_SUBPARTITIONS WHERE index_name = 'LOCAL_IDX_FOR_RANGE_RANGE_TB';Modify the columnar storage attribute of a table.
Execute the following statement to create a
tbl1table.CREATE TABLE tbl1 (col1 INT PRIMARY KEY, col2 VARCHAR(50));Change the
tbl1table to a rowstore redundant table and then drop the rowstore redundant attribute.ALTER TABLE tbl1 ADD COLUMN GROUP(all columns, each column);ALTER TABLE tbl1 DROP COLUMN GROUP(all columns, each column);Change the
tbl1table to a columnstore table and then drop the columnstore attribute.ALTER TABLE tbl1 ADD COLUMN GROUP(each column);ALTER TABLE tbl1 DROP COLUMN GROUP(each column);
Modify the Skip Index attribute of a column in a table.
Execute the following statement to create a
test_skidxtable.CREATE TABLE test_skidx( col1 NUMBER SKIP_INDEX(MIN_MAX, SUM), col2 FLOAT SKIP_INDEX(MIN_MAX), col3 VARCHAR2(1024) SKIP_INDEX(MIN_MAX), col4 CHAR(10) );Change the Skip Index attribute of the
col2column in thetest_skidxtable toSUM.ALTER TABLE test_skidx MODIFY col2 FLOAT SKIP_INDEX(SUM);Add a Skip Index attribute to a new column when creating a table. Add the
MIN_MAXSkip Index attribute to thecol4column in thetest_skidxtable.ALTER TABLE test_skidx MODIFY col4 CHAR(10) SKIP_INDEX(MIN_MAX);Drop the Skip Index attribute from a column when creating a table. Drop the Skip Index attribute from the
col1column in thetest_skidxtable.ALTER TABLE test_skidx MODIFY col1 NUMBER SKIP_INDEX();
To modify the table property and disable the persistent macro block-level bloom filter for table
tb, execute the following command:ALTER TABLE tb SET enable_macro_block_bloom_filter = False;
Read-only and read/write tables in an Oracle tenant
In an Oracle tenant, you can execute the CREATE TABLE statement to create tables with the READ ONLY or READ WRITE attribute. You can also execute the ALTER TABLE statement to change the read/write attribute of a table.
Notice
A user with the SUPER privilege cannot perform the related operations. We recommend that you use a normal user.
Procedure:
Create a normal user:
CREATE USER test1 IDENTIFIED BY "12345";Grant the connection and table creation privileges to the user:
GRANT CREATE SESSION TO test1; GRANT CREATE TABLE TO test1;Connect to OceanBase Database as the user:
obclient -hxxx.xx.xxx.xxx -P2881 -utest1@oracle001 -ACreate a read-only table:
CREATE TABLE tb_readonly1(id INT) READ ONLY;Insert data into the read-only table (expected to fail):
INSERT INTO tb_readonly1 VALUES (1); -- Expected error: ORA-00600: internal error code, arguments: -5235, The table 'TEST1.TB_READONLY1' is read only so it cannot execute this statementCreate a read/write table:
CREATE TABLE tb_readwrite1(id INT) READ WRITE;Insert data into the read/write table (expected to succeed):
INSERT INTO tb_readwrite1 VALUES (99),(98); -- Expected result: Query OK, 2 rows affected (0.002 sec) -- Records: 2 Duplicates: 0 Warnings: 0Convert the read/write table to a read-only table:
ALTER TABLE tb_readwrite1 READ ONLY;Insert data into the converted read-only table (expected to fail):
INSERT INTO tb_readwrite1 VALUES (96),(97); -- Expected error: ORA-00600: internal error code, arguments: -5235, The table 'TEST1.TB_READWRITE1' is read only so it cannot execute this statement