【问题标题】:create full copy of existing table in oracle在 oracle 中创建现有表的完整副本
【发布时间】:2018-10-08 06:47:47
【问题描述】:

我知道我可以很容易地用create table t1 select * from table2;创建一个表的副本但是我需要复制:

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

有没有办法通过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;

【问题讨论】:

    标签: sql oracle plsql


    【解决方案1】:

    你可以使用DBMS_REDEFINITION包,那个东西可以做一个包括cmets等在内的整个表的副本。它还会对新副本进行“碎片整理”以比原始表占用更少的空间。

    更多信息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;
    

    在这里您可以设置并行化等,准备数据等。 一切完成后,让我们开始 REDEFINITION 过程:

    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;
    

    希望对你有帮助。

    【讨论】:

    • 你能举例说明如何使用这个包吗?
    • 解释得很好。
    • 看来这需要由 SYSDBA 运行或授予。
    【解决方案2】:

    如果您使用 TOAD、SQL DEVELOPER,您可以在 toad 中使用 f4 并在 SQL developer 中使用 search abject 和 SQL 来访问表 SQL。这将为您提供创建表的 SQL 脚本。这将包含所有索引、默认值、列结构、授权、列 cmets,表空间。对于触发器,您可以从上述方法的 DBA_triggers/Triggers 部分获取此信息。只需更改表名并执行语句,然后将基表中的所有数据插入新表即可。

    【讨论】:

    • 这是我确定的最好的方法。
    猜你喜欢
    • 1970-01-01
    • 2015-01-03
    • 1970-01-01
    • 1970-01-01
    • 2011-10-18
    • 2015-04-28
    • 1970-01-01
    • 1970-01-01
    • 2016-06-03
    相关资源
    最近更新 更多