【问题标题】:How can I create a copy of an Oracle table without copying the data?如何在不复制数据的情况下创建 Oracle 表的副本?
【发布时间】:2010-09-19 00:45:45
【问题描述】:

我知道声明:

create table xyz_new as select * from xyz;

复制结构和数据,但如果我只想要结构怎么办?

【问题讨论】:

标签: sql oracle copy database-table


【解决方案1】:

使用sql developer选择表并点击DDL选项卡

当您在 sql 工作表中运行该代码时,您可以使用该代码创建一个没有数据的新表

sqldeveloper 是来自 oracle 的免费应用程序。

如果表有序列或触发器,ddl 有时也会为您生成这些。您只需要注意您制作它们的顺序并知道何时打开或关闭触发器。

【讨论】:

  • 在 Oracle SQL Developer v.18.3 中,该选项卡称为 SQL
【解决方案2】:

只需使用不会选择任何行的 where 子句:

create table xyz_new as select * from xyz where 1=0;

限制

以下内容不会复制到新表中:

  • 序列
  • 触发器
  • 索引
  • 可能无法复制某些约束
  • 物化视图日志

这也不处理分区


【讨论】:

  • 这是一个很好的、干净的答案。只是想提醒一下,这将包含任何约束..新表甚至没有主键。
  • 这也不会复制序列或触发器。
  • 新表也不会有任何索引 - 不要在尝试对新表进行大查询时被抓到 :-)
  • 也不处理分区。但是,嘿。
  • 只是一个附录——它包含一些约束——即任何非空约束都将被复制。
【解决方案3】:

我使用了您经常接受的方法,但正如有人指出的那样,它不会重复约束(我认为 NOT NULL 除外)。

如果要复制完整结构,更高级的方法是:

SET LONG 5000
SELECT dbms_metadata.get_ddl( 'TABLE', 'MY_TABLE_NAME' ) FROM DUAL;

这将为您提供完整的创建语句文本,您可以根据需要对其进行修改以创建新表。当然,您必须更改表的名称和所有约束。

(您也可以在旧版本中使用 EXP/IMP 执行此操作,但现在要容易得多。)

编辑添加 如果您之后的表在不同的架构中:

SELECT dbms_metadata.get_ddl( 'TABLE', 'MY_TABLE_NAME', 'OTHER_SCHEMA_NAME' ) FROM DUAL;

【讨论】:

  • 如果我想从另一个模式复制这个命令将如何修改。
  • My_table_name 是现有表。但是我如何获得创建的新表的名称?
  • 我的答案中的命令不会创建新表;它返回用于重新创建原始表的 SQL。您可以根据需要对其进行修改,然后运行它。因此,新表的名称是您选择指定的任何名称。
  • 所以它必须像将上面的sql命令分配给一个变量。赖特?例如。 new_table = dbms_metadata.get_ddl( 'TABLE', 'MY_TABLE_NAME', 'OTHER_SCHEMA_NAME' ). 同时请让我知道 LONG 在这里做什么。
【解决方案4】:

你也可以做一个

create table abc_new as select * from abc; 

然后截断表abc_new。希望这能满足您的要求。

【讨论】:

  • 当然,如果原始表中有大量数据,这可能是一个非常非常糟糕的主意。 ;)
【解决方案5】:

上面的任务可以通过两个简单的步骤完成。

第 1 步:

CREATE table new_table_name AS(Select * from old_table_name);

上面的query 创建了一个表的副本(也包含内容)。

要获取结构,使用删除表的内容。

第 2 步:

DELETE * FROM new_table_name.

希望这能解决您的问题。并感谢之前的帖子。给了我很多见解。

【讨论】:

  • 这比truncate 版本效率更低。除了为所有数据分配范围外,您并没有通过删除来释放它们,因此除非表增长到旧大小,否则您可能会浪费空间。而且您在插入和删除时都生成撤消/重做。吉姆的回答非常简单地避免了所有这些。
【解决方案6】:
create table xyz_new as select * from xyz where rownum = -1;

为了避免一次又一次地迭代,并且根据 1=2 的条件不插入任何内容

【讨论】:

    【解决方案7】:

    只需编写如下查询:

    create table new_table as select * from old_table where 1=2;
    

    其中new_table 是您要创建的新表的名称,old_table 是您要复制其结构的现有表的名称,这将只复制结构。

    【讨论】:

      【解决方案8】:
      Create table target_table 
      As
      Select * 
      from source_table 
      where 1=2;
      

      Source_table 是您要复制其结构的表。

      【讨论】:

        【解决方案9】:

        使用 pl/sql developer,您可以在 sql 工作区或对象资源管理器中右键单击 table_name,然后单击“查看”,然后单击“查看 sql”,它会生成 sql 脚本来创建表所有约束、索引、分区等。

        接下来您使用 new_table_name 运行脚本

        【讨论】:

          【解决方案10】:

          通过其他方式,您可以从下面列出的命令中获取创建表的 ddl,然后执行创建。

          SELECT DBMS_METADATA.GET_DDL('TYPE','OBJECT_NAME','DATA_BASE_USER') TEXT FROM DUAL 
          
          • TYPETABLE,PROCEDURE 等等。

          使用此命令,您可以从数据库对象中获取大部分 ddl。

          【讨论】:

          • 请注意GET_DDL 的参数区分大小写。
          【解决方案11】:

          你可以这样做 Create table New_table as select * from Old_table where 1=2 ; 但要小心 你创建的表没有old_table那样的Index、PK等。

          【讨论】:

            【解决方案12】:
                DECLARE
                l_ddl   VARCHAR2 (32767);
            BEGIN
                l_ddl      := REPLACE (
                                  REPLACE (
                                      DBMS_LOB.SUBSTR (DBMS_METADATA.get_ddl ('TABLE', 'ACTIVITY_LOG', 'OLDSCHEMA'))
                                    , q'["OLDSCHEMA"]'
                                    , q'["NEWSCHEMA"]'
                                  )
                                , q'["OLDTABLSPACE"]'
                                , q'["NEWTABLESPACE"]'
                              );
            
                EXECUTE IMMEDIATE l_ddl;
            END; 
            

            【讨论】:

              【解决方案13】:

              复制没有表格数据

              create table <target_table> as select * from <source_table> where 1=2;
              

              复制表格数据

              create table <target_table> as select * from <source_table>;
              

              【讨论】:

                【解决方案14】:
                SELECT * INTO newtable
                FROM oldtable
                WHERE 1 = 0;
                

                使用另一个架构创建一个新的空表。只需添加一个导致查询不返回数据的 WHERE 子句:

                【讨论】:

                  【解决方案15】:

                  WHERE 1 = 0 或类似的错误条件有效,但我不喜欢它们的外观。 Oracle 12c+ 恕我直言,代码略干净

                  CREATE TABLE bar AS SELECT * FROM foo FETCH FIRST 0 ROWS ONLY;

                  同样的限制适用:只有列定义及其可空性被复制到新表中。

                  【讨论】:

                    【解决方案16】:
                    1. create table xyz_new as select * from xyz;

                    -- 这将创建表并复制所有数据。

                    1. 从 xyz_new 中删除;

                    -- 这将具有相同的表结构,但所有复制的数据都将被删除。

                    如果您想克服 answer 指定的限制: How can I create a copy of an Oracle table without copying the data?

                    【讨论】:

                      【解决方案17】:

                      如果需要创建一个表(具有空结构)只是为了EXCHANGE PARTITION,最好使用“..FOR EXCHANGE..”子句。不过,它仅适用于 Oracle 版本 12.2 及以后的版本。

                      CREATE TABLE t1_temp FOR EXCHANGE WITH TABLE t1;
                      

                      如果表结构没有被正常的 CTAS 操作完全复制,这将在“交换分区”期间无缝解决“ORA-14097”。我看到 Oracle 缺少原始表中的一些“DEFAULT”列和“HIDDEN”列定义。

                      ORA-14097: ALTER TABLE EXCHANGE 中的列类型或大小不匹配 分区

                      See this for further read...

                      【讨论】:

                        猜你喜欢
                        • 2019-05-12
                        • 1970-01-01
                        • 1970-01-01
                        • 2015-11-02
                        • 2016-02-24
                        • 2017-12-28
                        • 2021-01-16
                        • 1970-01-01
                        • 2013-03-12
                        相关资源
                        最近更新 更多