最常用的表复制方法,复制表结构和数据:
-- 复制表结构和所有数据
CREATE TABLE new_table AS SELECT * FROM original_table;
-- 复制表结构并筛选数据
CREATE TABLE new_table AS
SELECT * FROM original_table WHERE condition;
-- 复制部分列
CREATE TABLE new_table AS
SELECT col1, col2, col3 FROM original_table;
-- 复制空表(仅结构)
CREATE TABLE new_table AS
SELECT * FROM original_table WHERE 1=0;
使用 SQL Developer 图形界面:
在左侧连接窗口中右键点击源表 选择 "复制" → "复制到..." 选择目标连接和方案 可以选择:-- 生成插入语句
SELECT 'INSERT INTO new_table VALUES ('
|| col1 || ', ' || col2 || ', ...' || ');'
FROM original_table;
-- 复制到其他用户的方案
CREATE TABLE other_user.new_table AS
SELECT * FROM current_user.original_table;
-- 需要相应权限
GRANT SELECT ON original_table TO other_user;
-- 复制表结构包括约束、索引等
BEGIN
DBMS_METADATA.SET_TRANSFORM_PARAM(
DBMS_METADATA.SESSION_TRANSFORM,
'SQLTERMINATOR', TRUE);
SELECT DBMS_METADATA.GET_DDL('TABLE', 'ORIGINAL_TABLE')
INTO :ddl FROM DUAL;
EXECUTE IMMEDIATE :ddl;
END;
/
-- 使用 DBMS_REDEFINITION 在线重定义(大型表)
BEGIN
DBMS_REDEFINITION.CAN_REDEF_TABLE('USER', 'ORIGINAL_TABLE');
DBMS_REDEFINITION.START_REDEF_TABLE(
uname => 'USER',
orig_table => 'ORIGINAL_TABLE',
int_table => 'INTERIM_TABLE');
DBMS_REDEFINITION.FINISH_REDEF_TABLE(
uname => 'USER',
orig_table => 'ORIGINAL_TABLE',
int_table => 'INTERIM_TABLE');
END;
/
-- 前提:目标表已存在
INSERT INTO target_table
SELECT * FROM source_table;
-- 指定列插入
INSERT INTO target_table (col1, col2, col3)
SELECT col1, col2, col3 FROM source_table;
-- 1. 复制结构
CREATE TABLE new_table AS
SELECT * FROM original_table WHERE 1=0;
-- 2. 手动添加约束
ALTER TABLE new_table ADD CONSTRAINT pk_new PRIMARY KEY (id);
ALTER TABLE new_table ADD CONSTRAINT fk_new FOREIGN KEY (ref_id)
REFERENCES other_table(id);
-- 3. 复制索引
CREATE INDEX idx_new_col ON new_table(column_name);
-- 禁用约束和索引提高插入速度
ALTER TABLE new_table DISABLE CONSTRAINT constraint_name;
ALTER INDEX index_name UNUSABLE;
-- 使用并行和NOLOGGING(生产环境慎用)
CREATE TABLE new_table NOLOGGING PARALLEL 4 AS
SELECT /*+ PARALLEL(4) */ * FROM original_table;
-- 分批次插入大表
INSERT /*+ APPEND */ INTO new_table
SELECT * FROM original_table WHERE ROWNUM <= 10000;
-- 复制前确认表空间
SELECT tablespace_name, bytes/1024/1024 MB
FROM user_segments
WHERE segment_name = 'ORIGINAL_TABLE';
-- 检查行数
SELECT COUNT(*) FROM original_table;
SELECT COUNT(*) FROM new_table;
-- 数据对比
SELECT '差异数据' AS remark, a.*
FROM (
SELECT * FROM original_table
MINUS
SELECT * FROM new_table
) a;
根据你的具体需求(是否需要数据、是否需要约束索引、表的大小等)选择合适的方法。