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) 显式定义列属性

若子查询中包含表达式或动态值(如 CASENVL),需用 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. 总结步骤

  1. 编写子查询‌ → 明确需要复制的数据或结构。
  2. 处理数据类型‌ → 对表达式或空值列显式定义类型(如 CAST)。
  3. 优化存储参数‌ → 根据数据量设置并行度、表空间等。
  4. 验证结果‌ → 使用 DESC new_table 检查结构,SELECT * FROM new_table 验证数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值