如何使用CREATE TABLE AS语句添加IDENTITY列?
解决方法:创建带IDENTITY列的新表并导入原表数据
你原来的语句报错是因为IDENTITY是列的属性定义,不能在SELECT子句的CAST中指定——CREATE TABLE AS SELECT(CTAS)语法只能复制原表的数据和列的基本数据类型,没法直接在SELECT里定义IDENTITY这类列属性。下面给你两种可行的方案,适用于Oracle 12c及以上版本(因为IDENTITY是Oracle 12c引入的特性):
方案一:先创建带IDENTITY列的空表,再插入数据
这种方法更灵活,能明确控制列的数据类型和IDENTITY的配置:
- 先清理旧表(如果存在):
DROP TABLE A_TEST PURGE; -- PURGE可选,用于跳过回收站直接删除
- 创建包含IDENTITY列的空表,注意要和原表
A的C_CODE、B_CODE列数据类型保持一致:
CREATE TABLE A_TEST ( ROW_ID NUMBER GENERATED BY DEFAULT AS IDENTITY, -- 可自定义配置,比如START WITH 1 INCREMENT BY 1 C_CODE VARCHAR2(50), -- 替换成表A中C_CODE的实际数据类型,比如NUMBER(10) B_CODE NUMBER(10) -- 替换成表A中B_CODE的实际数据类型 );
提示:如果需要自定义IDENTITY的起始值、增量,可以在后面追加
START WITH 100 INCREMENT BY 2这类参数。
- 把原表
A的数据插入到新表中,无需指定ROW_ID,IDENTITY列会自动生成值:
INSERT INTO A_TEST (C_CODE, B_CODE) SELECT C_CODE, B_CODE FROM A; COMMIT; -- 提交插入操作
方案二:先通过CTAS创建表,再添加IDENTITY列
如果不想手动写列的数据类型,可以先用CTAS复制原表结构和数据,再添加IDENTITY列:
- 删除旧表并创建基础表:
DROP TABLE A_TEST PURGE; CREATE TABLE A_TEST AS SELECT C_CODE, B_CODE FROM A;
- 给新表添加IDENTITY列,Oracle会自动为现有行填充递增的ID值:
ALTER TABLE A_TEST ADD ROW_ID NUMBER GENERATED BY DEFAULT AS IDENTITY;
注意:如果原表数据量很大,添加IDENTITY列的操作可能会耗时,因为需要为每一行生成ID值。
为什么你的原语句会报错?
CAST(null as NUMBER GENERATED BY DEFAULT AS IDENTITY)是错误的写法——IDENTITY不是数据类型的一部分,它是列的约束/属性,只能在CREATE TABLE的列定义中指定,不能在SELECT的表达式里用CAST来定义。
内容的提问来源于stack exchange,提问作者Moudiz
相关产品推荐
相关产品推荐

