CREATE TABLE ... AS SELECT
在 Oracle 中,使用 CREATE TABLE ... AS SELECT
(CTAS) 语法可以通过子查询从现有表快速创建新表。以下是详细操作指南及注意事项:
1. 基础语法
CREATE TABLE new_table_name AS
SELECT column1, column2, ...
FROM existing_table
WHERE conditions;
示例:从 employees
表创建新表 emp_backup
,仅包含部门号为 10 的员工
CREATE TABLE emp_backup
AS SELECT employee_id, first_name, last_name, salary
FROM employees
WHERE department_id = 10;
2. 关键注意事项
(1) 复制表结构不复制数据
添加 WHERE 1=0
条件,创建空表:
CREATE TABLE emp_structure AS
SELECT * FROM employees
WHERE 1 = 0; -- 不复制数据,仅复制表结构
(2) 显式定义列属性
若子查询中包含表达式或动态值(如 CASE
、NVL
),需用 CAST
指定数据类型,避免隐含错误(如 ORA-01723)
CREATE TABLE emp_salary
AS SELECT employee_id,
CAST(NVL(salary, 0) AS NUMBER(10,2)) adjusted_salary -- 显式定义类型 FROM employees;
(3) 处理存储参数
指定表空间、并行度等参数(适用于大数据量场景):
CREATE TABLE large_data_table PARALLEL 8 -- 并行度
NOLOGGING -- 减少日志生成
TABLESPACE users -- 指定表空间 AS SELECT * FROM source_table;
(4) 索引与约束
- CTAS 不会复制原表的索引、主键、外键等约束(仅保留
NOT NULL
约束)。 - 需手动为新表添加索引和约束:
ALTER TABLE emp_backup
-
ADD PRIMARY KEY (employee_id);
-
CREATE INDEX idx_emp_name ON emp_backup(last_name);
3. 高级用法
(1) 合并多表数据
通过子查询联合多个表创建新表:
CREATE TABLE combined_data AS SELECT e.employee_id, e.first_name, d.department_name FROM employees e JOIN departments d ON e.department_id = d.department_id;
(2) 动态生成数据
使用函数或计算列生成新数据:
CREATE TABLE emp_bonus AS
SELECT employee_id, salary * 0.1 AS bonus, -- 计算奖金
TO_CHAR(hire_date, 'YYYY-MM') AS hire_month -- 格式化日期 FROM employees;
4. 常见问题
(1) 权限不足
- 错误:
ORA-01031: insufficient privileges
- 解决:确保用户拥有
CREATE TABLE
权限及对原表的SELECT
权限:GRANT CREATE TABLE TO your_user; GRANT SELECT ON employees TO your_user;
(2) 表名冲突
- 错误:
ORA-00955: name is already used by an existing object
- 解决:删除或重命名已存在的表:
DROP TABLE emp_backup; -- 删除旧表
-- 或
CREATE TABLE emp_backup_new AS ...; -- 使用新表名
5. 总结步骤
- 编写子查询 → 明确需要复制的数据或结构。
- 处理数据类型 → 对表达式或空值列显式定义类型(如
CAST
)。 - 优化存储参数 → 根据数据量设置并行度、表空间等。
- 验证结果 → 使用
DESC new_table
检查结构,SELECT * FROM new_table
验证数据。