首批通过分布式安全可靠测评,为关键业务系统打造
ALTER TABLE
更新时间:2026-06-01 17:50:59
描述
该语句用来修改已存在的表的结构,包括修改表及表属性、新增列、修改列及属性、删除列等。
语法
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)
| SET INTERVAL(expr)
| COLUMN_NAME_CASE_SENSITIVE [=] {True | False}
| DELTA_FORMAT [=] 'flat | encoding'
| SET TTL col_name + INTERVAL interval_num ttl_unit BY { COMPACTION | DELETING }
| REMOVE TTL
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 */
语法说明
| 参数 | 描述 |
|---|---|
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 (...) LOCATION STRING_VALUE |
为外部表添加分区 |
ALTER TABLE EXTERNAL table_name DROP PARTITION LOCATION STRING_VALUE |
删除外部表分区 |
table_option_list_space_seperated |
设置表的各种选项 |
SET table_option_list_space_seperated |
通过 SET 语句设置表选项 |
ENABLE ROW MOVEMENT |
启用行移动。当分区表中主键或唯一键被更新导致行可能跨分区移动时,允许该行移动至其他分区。 |
DISABLE ROW MOVEMENT |
禁用行移动。当分区表中主键或唯一键被更新导致行可能跨分区移动时,禁止该行移动至其他分区,UPDATE 操作将失败。 |
opt_alter_compress_option |
修改表的压缩选项 |
alter_column_option |
修改列定义 |
alter_tablegroup_option |
修改表组选项 |
RENAME relation_factor |
重命名表 |
DROP CONSTRAINT constraint_name |
删除约束 |
REFRESH |
刷新表 |
enable_macro_block_bloom_filter |
用于指定是否持久化宏块级别 bloom filter。取值如下:
|
DROP PARTITION partition_name |
删除指定分区 |
RENAME PARTITION old_name TO new_name |
重命名分区。重命名一级或者二级分区,new_name 指定要修改分区的新分区名称(大小写不敏感)。分区重命名操作会修改主表的相关分区,但是不会影响到局部索引的分区名,可以通过视图 USER_TAB_PARTITIONS 和 USER_TAB_SUBPARTITIONS 确认分区名修改后的结果,详细信息请参见重命名分区。分区重命名过程中,如果与持有相关分区锁资源的 DML 产生冲突会阻塞分区名修改操作,直到 DML 释放相关分区锁资源。 |
SPLIT PARTITION partition_name split_actions |
拆分分区。用于手动分区分裂,有 split_at_format 和 split_into_format 两种格式,详细介绍可参见下文 split_partition_option。 |
TRUNCATE PARTITION partition_name |
清空分区数据 |
MODIFY PARTITION partition_name ... |
修改分区属性。表示新增二级分区。
注意不支持二级分区类型是 Hash 类型的场景新增二级分区。 |
ADD COLUMN GROUP (column_list) [DELAYED] |
添加列组。将表变更为列存表。具体解释如下:
|
DROP COLUMN GROUP (column_list) [DELAYED] |
删除列组。移除表的存储格式。具体解释如下:
|
MODIFY hash_partition_option |
修改哈希分区 |
MODIFY list_partition_option |
修改列表分区 |
MODIFY range_partition_option |
修改范围分区 |
PARTITION BY RANGE (...) opt_auto_split_tablet_size_option |
设置范围分区的自动分割 |
AUTO_SPLIT_TABLET_SIZE (size) |
设置分区自动分割的大小阈值 |
add_external_table_partition_action |
定义外部表分区的具体属性 |
add_external_table_partition_actions ',' action |
多个外部表分区定义 |
ADD |
增加列,目前不支持增加主键列 |
MODIFY COLUMN |
修改列属性 |
MODIFY CONSTRAINT |
修改约束的状态为开启或关闭,只支持外键约束和 CHECK 约束 |
DROP PRIMARY KEY |
删除主键。
说明对于 Oracle 模式,如果表是外键信息的父表,则不允许删除主键。 |
EXCHANGE {PARTITION partition_name \| SUBPARTITION subpartition_name} WITH TABLE origin_table_name INCLUDING INDEXES WITHOUT VALIDATION |
指定分区交换。其中:
|
| DYNAMIC_PARTITION_POLICY [=] (dynamic_partition_policy_list) | 修改表的动态分区管理属性。dynamic_partition_policy_list 动态分区策略的可配置参数列表,各参数用英文逗号分隔,详细介绍可参见下文 dynamic_partition_policy_option。 |
| SET INTERVAL(expr) | 用于 Range 分区表与 Interval 分区表之间的相互转换。详细介绍可参见 修改分区规则 中的修改分区类型。 |
| COLUMN_NAME_CASE_SENSITIVE [=] {True | False} | 用于设置生成列的列名是否区分大小写。
|
| TTL col_name + INTERVAL interval_num ttl_unit BY { COMPACTION | DELETING } | 修改表的 TTL 策略。具体解释如下:
|
| REMOVE TTL | 表示删除表的 TTL 策略。 |
| DELTA_FORMAT [=] 'flat | encoding' | 用于设置增量数据的存储格式,取值如下:
说明修改 |
| SKIP_INDEX_LEVEL [=] {1 | 0} | 用于设置增量 SSTable 按照基线的行为生成 Skip Index 聚合信息,取值如下:
|
split_partition_option
SPLIT PARTITION partition_name AT (value) [INTO (PARTITION split_partition_name1, PARTITION [split_partition_name2])]:使用此语法分区分裂时,将会以给定的value为界限,将源分区分裂为两个分区。也可以使用INTO子句给分裂出的分区设置名称。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):使用此语法分区分裂时,可以将一个分区分裂为多个分区,分区分裂所定义的value范围需要保证与源分区的value范围相同,且需要保证按升序定义value(不允许填写最后一个分区分裂的定义,其value等同于源分区)。
更多有关手动分区分裂的信息,参见 手动分区分裂。
dynamic_partition_policy_option
ENABLE = {true | false}:表示是否启用动态分区管理。取值如下:true:默认值,表示启用动态分区管理。false:表示禁用动态分区管理。
PRECREATE_TIME = {'-1' | '0' | 'n {hour | day | week | month | year}'}:表示预创建时间。调度一次动态分区管理,会预创建分区使得 最大分区上界 > now() + precreate_time。取值如下:-1:默认值,表示不预创建分区。0:表示仅预创建当前分区。n {hour | day | week | month | year}:表示预创建对应时间跨度的分区。例如,3 hour表示预创建 3 小时内的分区。
说明
- 需要预创建多个分区时,分区边界的间隔为
TIME_UNIT。 - 首个预创建的分区边界为现存最大分区边界按
TIME_UNIT向上取整。
EXPIRE_TIME = {'-1' | '0' | 'n {hour | day | week | month | year}'}:可选项,表示分区过期时间。调度一次动态分区管理,会删除所有 分区上界 < now() - expire_time 的过期分区。可修改,取值如下:-1:默认值,表示分区永不过期。0:表示除当前分区外,之前的所有分区均过期。n {hour | day | week | month | year}:表示分区过期时间。例如,1 day表示分区过期时间为 1 天。
更多有关修改动态分区表的信息,参见 修改动态分区表。
示例如下:
ALTER TABLE tbl2 SET DYNAMIC_PARTITION_POLICY(
ENABLE = true,
PRECREATE_TIME = '1 day',
EXPIRE_TIME = '-1'
);
示例
修改表
tbl1中字段col1的字段类型。obclient> CREATE TABLE tbl1(col1 VARCHAR(3)); obclient> ALTER TABLE tbl1 MODIFY col1 CHAR(10); obclient> DESCRIBE tbl1;修改表
tbl1中列col1的名称为col2。obclient> ALTER TABLE tbl1 RENAME COLUMN col1 TO col2; obclient> DESCRIBE tbl1;增加和删除列。
创建表
tbl2。obclient> CREATE TABLE tbl2 (col1 NUMBER(30) PRIMARY KEY,col2 VARCHAR(50));对表
tbl2增加col3列。obclient> ALTER TABLE tbl2 ADD col3 NUMBER(30); obclient> DESCRIBE tbl2;删除表
tbl2的col3列。obclient> ALTER TABLE tbl2 DROP COLUMN col3; obclient> DESCRIBE tbl2;为表
tbl2创建唯一性索引。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');
为表
ref_t2添加外键,当DELETE操作影响与子表相匹配行的父表中键值时,执行SET NULL操作。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;为非模板化二级分区表
tbl3的一级分区p1下添加二级分区p1_r4。obclient> ALTER TABLE tbl3 MODIFY PARTITION p1 ADD SUBPARTITION p1_r4 VALUES LESS THAN(2022);删除非模板化二级分区表
tbl3的二级分区p3_r3。obclient> ALTER TABLE tbl3 DROP SUBPARTITION p2_r3;为非模板化二级分区表
tbl3添加一级分区p4,需要同时指定一级分区的定义和该分区下的二级分区定义。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) );为模板化二级分区表
tbl4添加一级分区p3,只需要指定一级分区的定义,二级分区的定义会自动按照模板填充。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);修改表
tbl5的并行度为3。obclient> CREATE TABLE tbl5(col1 int primary key, col2 int) PARALLEL 5; obclient> ALTER TABLE tbl5 PARALLEL 3;或者:
obclient> CREATE TABLE tbl5(col1 int primary key, col2 int) PARALLEL 5; obclient> ALTER /*+ parallel(3) */ TABLE tbl5;修改外键约束的状态。
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%';清空分区表
tbl6的分区M202001和M202002中的全部数据。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;删除表
tbl7的CHECK约束tbl7_equal_check1。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%';把表
tbl8从表组tblgroup1中移到表组tblgroup2中。obclient> SHOW TABLEGROUPS; obclient> ALTER TABLE tbl8 SET TABLEGROUP tblgroup2; obclient> SHOW TABLEGROUPS;为表
primary_table添加外键约束cons_fk1。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);为表
tbl9添加主键约束tbl1_pk。obclient> CREATE TABLE tbl9 (col1 NUMBER, col2 INT,col3 VARCHAR2(100)); obclient> ALTER TABLE tbl9 ADD CONSTRAINT tbl1_pk PRIMARY KEY (col1);修改表
tbl9的主键为col2列。obclient> ALTER TABLE tbl9 MODIFY PRIMARY KEY(col2);删除表
tbl9的主键。obclient> ALTER TABLE tbl9 DROP PRIMARY KEY;重命名一级分区和二级分区。
/* 创建二级分区表 range_range_table 并基于 col1 创建本地索引 */ 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; /* 重命名一级分区,但修改不会影响到局部索引的分区名 */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'; /* 重命名二级分区,但修改不会影响到局部索引的分区名 */ 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';修改表的列存属性。
使用下面 SQL 语句创建表
tbl1。CREATE TABLE tbl1 (col1 INT PRIMARY KEY, col2 VARCHAR(50));将表
tbl1的变更为行存列存冗余表,然后再删除行存列存冗余属性。ALTER TABLE tbl1 ADD COLUMN GROUP(all columns, each column);ALTER TABLE tbl1 DROP COLUMN GROUP(all columns, each column);将表
tbl1的变更为列存表,然后再删除列存属性。ALTER TABLE tbl1 ADD COLUMN GROUP(each column);ALTER TABLE tbl1 DROP COLUMN GROUP(each column);
修改表中列的 Skip Index 属性。
使用下面 SQL 语句创建表
test_skidx。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) );修改表
test_skidx中列col2的 Skip Index 属性为SUMSkip Index 类型。ALTER TABLE test_skidx MODIFY col2 FLOAT SKIP_INDEX(SUM);建表后新增列的 Skip Index 属性。为表
test_skidx中列col4增加的MIN_MAXSkip Index 类型。ALTER TABLE test_skidx MODIFY col4 CHAR(10) SKIP_INDEX(MIN_MAX);建表后删除列的 Skip Index 属性。删除表
test_skidx中列col1的 Skip Index 属性。ALTER TABLE test_skidx MODIFY col1 NUMBER SKIP_INDEX();
修改表属性,执行如下命令关闭持久化宏块级别 bloom filter 的表
tb。ALTER TABLE tb SET enable_macro_block_bloom_filter = False;为分区表启用或禁用行移动。
-- 启用行移动,允许 UPDATE 导致的分区键变更时行跨分区移动 ALTER TABLE partitioned_tbl ENABLE ROW MOVEMENT; -- 禁用行移动 ALTER TABLE partitioned_tbl DISABLE ROW MOVEMENT;修改表的 TTL 策略。例如:将数据过期时间修改为 1 小时。
obclient(SYS@oracle001)[SYS]> ALTER TABLE TTL_TBL1 SET TTL ORA_ROWSCN + INTERVAL 1 HOUR BY COMPACTION;删除表的 TTL 策略。
obclient(SYS@oracle001)[SYS]> ALTER TABLE TTL_TBL1 SET REMOVE TTL;
Oracle 租户下的只读和读写表
在 Oracle 租户下,您可以使用 CREATE TABLE 创建 READ ONLY 和 READ WRITE 类型的表。您也可以使用 ALTER TABLE 语句更改表的读写属性。
注意
拥有 SUPER 权限的用户无法成功执行相关操作,建议使用普通用户。
操作步骤:
创建普通用户:
CREATE USER test1 IDENTIFIED BY "12345";授予用户连接和建表权限:
GRANT CREATE SESSION TO test1; GRANT CREATE TABLE TO test1;使用普通用户连接 OceanBase 数据库:
obclient -hxxx.xx.xxx.xxx -P2881 -utest1@oracle001 -A创建只读表:
CREATE TABLE tb_readonly1(id INT) READ ONLY;尝试向只读表插入数据(预期失败):
INSERT INTO tb_readonly1 VALUES (1); -- 预期报错:ORA-00600: internal error code, arguments: -5235, The table 'TEST1.TB_READONLY1' is read only so it cannot execute this statement创建读写表:
CREATE TABLE tb_readwrite1(id INT) READ WRITE;向读写表插入数据(预期成功):
INSERT INTO tb_readwrite1 VALUES (99),(98); -- 预期结果:Query OK, 2 rows affected (0.002 sec) -- Records: 2 Duplicates: 0 Warnings: 0将读写表转换为只读表:
ALTER TABLE tb_readwrite1 READ ONLY;尝试向转换后的只读表插入数据(预期失败):
INSERT INTO tb_readwrite1 VALUES (96),(97); -- 预期报错:ORA-00600: internal error code, arguments: -5235, The table 'TEST1.TB_READWRITE1' is read only so it cannot execute this statement