在oracle中创建现有表的完整副本

时间:2018-10-08 06:47:48

标签: sql oracle plsql

我知道我可以轻松地使用create table t1 select * from table2;创建表的副本,但是我需要复制:

  • 评论
  • 表空间
  • 索引
  • 拨款
  • 触发器
  • 默认值
  • ...
  • 任何其他依赖项

是否可以通过pl/sql过程来做到这一点?我的Oracle版本是 11R2

表的SQL:

-- Create table

    create table SCHEMA.MY_TABLE
    (
      id      number(1),
      name    varchar2(30),
      dat     date
    )
    tablespace MY_TS
      pctfree 10
      initrans 1
      maxtrans 255
      storage
      (
        initial 10M
        next 1M
        minextents 1
        maxextents unlimited
      );
    -- Add comments to the table 
    comment on table SCHEMA.MY_TABLE
      is 'MY TABLE';
    comment on column SCHEMA.MY_TABLE.ID
      is 'id';
    comment on column SCHEMA.MY_TABLE.NAME
      is 'name of operation';
    comment on column SCHEMA.MY_TABLE.DAT
      is 'date of operation';

    grant select on SCHEMA.MY_TABLE to PUBLIC;

2 个答案:

答案 0 :(得分:3)

您可以使用DBMS_REDEFINITION程序包,该程序可以对整个表进行复制,包括注释等。它还将对新副本进行“碎片整理”,以使其比原始表占用更少的空间。

更多信息,https://docs.oracle.com/database/121/ARPLS/d_redefi.htm#ARPLS042

根据请求的示例:

因此,让我们创建一个测试模式,一个表并向其中填充一些数据:

CREATE USER "TEST_SCHEMA" IDENTIFIED BY "TEST";
GRANT UNLIMITED TABLESPACE TO "TEST_SCHEMA";

CREATE TABLE "TEST_SCHEMA"."NAMES" ("ID" NUMBER, "NAME" VARCHAR2(25), PRIMARY KEY("ID"));

INSERT INTO "TEST_SCHEMA"."NAMES" VALUES (1, 'joe');
INSERT INTO "TEST_SCHEMA"."NAMES" VALUES (2, 'pete');
INSERT INTO "TEST_SCHEMA"."NAMES" VALUES (3, 'mark');

现在我们可以检查测试表的内容:

SELECT * FROM "TEST_SCHEMA"."NAMES";

让我们通过完全按照源表的外观创建空白表(使用WHERE 1=0,不接收任何数据)来开始复制过程。

CREATE TABLE "TEST_SCHEMA"."NAMES_COPY" AS SELECT * FROM "TEST_SCHEMA"."NAMES" "A1" WHERE 1=0;

在这里您可以设置并行化等,准备数据等。 完成所有操作后,让我们开始重新定义过程:

BEGIN
  DBMS_REDEFINITION.START_REDEF_TABLE('TEST_SCHEMA','NAMES','NAMES_COPY');
END;
/

复制内容时,我们需要复制依赖于表的每个对象(例如触发器,索引等...)

DECLARE
  num_errors PLS_INTEGER;
BEGIN
  DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS ('TEST_SCHEMA',  'NAMES',    'NAMES_COPY',
    DBMS_REDEFINITION.CONS_ORIG_PARAMS, TRUE, TRUE, TRUE, TRUE, num_errors);
END;
/

我们可以使用此查询检查在复制依赖项期间是否发生任何错误:

SELECT "OBJECT_NAME", "BASE_TABLE_NAME", "DDL_TXT" FROM DBA_REDEFINITION_ERRORS;

如果一切正常,我们可以完成此过程:

BEGIN
  DBMS_REDEFINITION.FINISH_REDEF_TABLE ('TEST_SCHEMA', 'NAMES',    'NAMES_COPY');
END;
/

瞧,新表就像克隆的绵羊多莉,里面有所有东西:

SELECT * FROM "TEST_SCHEMA"."NAMES_COPY";

现在要关闭测试模式,运行以下命令:

DROP TABLE "TEST_SCHEMA"."NAMES";
DROP TABLE "TEST_SCHEMA"."NAMES_COPY";
DROP USER "TEST_SCHEMA" CASCADE;

我希望它能帮上忙。

答案 1 :(得分:1)

如果使用的是TOAD,SQL DEVELOPER,则可以通过在Toad中使用f4并使用搜索对象然后在SQL Developer中使用SQL来访问表SQL。这将为您提供SQL脚本来创建表。这将具有所有索引,默认值,列结构,授权,列 注释,表空间。对于触发器,可以从上述方法的DBA_triggers / Triggers部分获得。只需更改表名并执行该语句,然后将所有数据从基表插入到新表中即可。