如何在不复制数据的情况下创建Oracle表的副本?


Answers:


420

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

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

局限性

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

  • 顺序
  • 触发器
  • 指标
  • 某些约束可能无法复制
  • 物化视图日志

这也不处理分区



53
这是一个很好的答案。只是要提醒您,这将包含任何约束..新表甚至没有主键。
JosephStyons

18
这不会复制序列或触发器。
branchgabriel

16
新表也不会有任何索引-不要在尝试对新表进行大查询时被抓住:-)
hamishmcn's

8
也不会处理分区。可是
MK。

17
只是一个附录-它包含一些限制-即任何NOT NULL约束将被复制。
杰弗里·肯普

84

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

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

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

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

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

编辑添加 如果您要使用的表位于不同的架构中:

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

如果要从另一个架构中复制,该命令将如何修改。
kushalvm

My_table_name是现有的表格。但是,如何获得创建的新表的名称?
kushalvm

我的答案中的命令不会创建新表;它返回用于重新创建原始表的SQL。您根据需要修改它,然后运行它。因此,新表的名称是您选择指定的名称。
戴夫·科斯塔

5
因此,必须像将上述sql命令分配给变量一样。ryt?例如。new_table = dbms_metadata.get_ddl( 'TABLE', 'MY_TABLE_NAME', 'OTHER_SCHEMA_NAME' ). 同时,请让我知道LONG在这里做什么。
kushalvm

15

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

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

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

如果表中包含序列或触发器,则ddl有时也会为您生成序列或触发器。您只需要注意按什么顺序排列它们,并知道何时打开或关闭触发器。


在Oracle SQL Developer v.18.3中,该选项卡称为SQL
Metafaniel

14
create table xyz_new as select * from xyz where rownum = -1;

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


4
    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; 

3

您可以执行此操作, Create table New_table as select * from Old_table where 1=2 ; 但要小心 ,您创建的表没有任何索引,Pk等,就像old_table


2
SELECT * INTO newtable
FROM oldtable
WHERE 1 = 0;

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


1

你也可以做一个

create table abc_new as select * from abc; 

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


11
当然,如果原始表中有很多数据,这可能是一个非常非常糟糕的主意。;)
Alexios

1

只需编写如下查询:

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

where new_table是要创建的新表old_table的名称,并且是要复制其结构的现有表的名称,这将仅复制结构。


1

WHERE 1 = 0或类似的错误条件起作用,但我不喜欢它们的外观。Oracle 12c + IMHO的边缘清洁代码是

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

应用相同的限制:仅将列定义及其可空性复制到新表中。


1

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

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

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


请注意,参数to GET_DDL区分大小写。
Sridhar Sarnobat,

0
Create table target_table 
As
Select * 
from source_table 
where 1=2;

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


0

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

接下来,您使用new_table_name运行脚本


0

没有表格数据的复制

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

复制表数据

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


-5

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

第1步:

CREATE table new_table_name AS(Select * from old_table_name);

query上述创建一个表的副本(具有内容以及)。

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

第2步:

DELETE * FROM new_table_name.

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


13
这甚至比truncate版本效率低。除了为所有数据分配扩展区之外,您还没有通过删除来释放它们,因此,除非表增长到旧的大小,否则可能浪费空间。并且您在插入和删除上都生成撤消/重做。吉姆的回答很简单地避免了所有这些。
亚历克斯·普尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.