我知道这样的说法:
create table xyz_new as select * from xyz;
哪个复制结构和数据,但如果我只想要结构怎么办?
只需使用不会选择任何行的 where 子句:
create table xyz_new as select * from xyz where 1=0;
限制
以下内容不会复制到新表中:
序列
触发器
索引
某些约束可能无法复制
物化视图日志
这也不处理分区
我使用了您经常接受的方法,但正如有人指出的那样,它不会重复约束(我认为 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
是现有表。但是我如何获得创建的新表的名称?
new_table = dbms_metadata.get_ddl( 'TABLE', 'MY_TABLE_NAME', 'OTHER_SCHEMA_NAME' ).
同时,请告诉我 LONG 在这里做什么。
create table xyz_new as select * from xyz where rownum = -1;
为了避免一次又一次地迭代并且根据 1=2 的条件不插入任何内容
FETCH NEXT 0 ROWS ONLY
- 一些互联网资源表明它可能比 rownum
更快,但对于这种情况,我认为比起性能,我更喜欢 FETCH
句子的可读性。可能更看个人喜好
使用 sql developer 选择表并单击 DDL 选项卡
当您在 sql 工作表中运行该代码时,您可以使用该代码创建一个没有数据的新表
sqldeveloper 是来自 oracle 的免费应用程序。
如果表有序列或触发器,则 ddl 有时也会为您生成这些。您只需要注意您制作它们的顺序并知道何时打开或关闭触发器。
SQL
您可以这样做Create table New_table as select * from Old_table where 1=2 ;
但要小心您创建的表没有任何索引、PK 等,如 old_table。
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;
只需编写如下查询:
create table new_table as select * from old_table where 1=2;
其中 new_table
是您要创建的新表的名称,old_table
是您要复制其结构的现有表的名称,这将只复制结构。
SELECT * INTO newtable
FROM oldtable
WHERE 1 = 0;
使用另一个模式创建一个新的空表。只需添加一个导致查询不返回数据的 WHERE 子句:
如果需要创建一个表(具有空结构)只是为了交换分区,最好使用“..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 PARTITION 中的列类型或大小不匹配
你也可以做一个
create table abc_new as select * from abc;
然后截断表 abc_new
。希望这能满足您的要求。
使用 pl/sql developer,您可以在 sql 工作区或对象资源管理器中右键单击 table_name,然后单击“查看”,然后单击“查看 sql”,生成 sql 脚本以创建表以及所有约束,索引,分区等。
接下来,您使用 new_table_name 运行脚本
复制没有表数据
create table <target_table> as select * from <source_table> where 1=2;
用表数据复制
create table <target_table> as select * from <source_table>;
WHERE 1 = 0
或类似的错误条件有效,但我不喜欢它们的外观。 Oracle 12c+ 恕我直言的稍微干净的代码是
CREATE TABLE bar AS SELECT * FROM foo FETCH FIRST 0 ROWS ONLY;
同样的限制适用:只有列定义及其可空性被复制到新表中。
以其他方式,您可以从下面列出的命令中获取表创建的 ddl,然后执行创建。
SELECT DBMS_METADATA.GET_DDL('TYPE','OBJECT_NAME','DATA_BASE_USER') TEXT FROM DUAL
TYPE 是 TABLE、PROCEDURE 等。
使用此命令,您可以从数据库对象中获取大部分 ddl。
GET_DDL
的参数区分大小写。
Create table target_table
As
Select *
from source_table
where 1=2;
Source_table 是您要复制其结构的表。
从 xyz 中选择 * 创建表 xyz_new;
-- 这将创建表并复制所有数据。
从 xyz_new 中删除;
-- 这将具有相同的表结构,但所有复制的数据都将被删除。
如果您想克服 answer 指定的限制:How can I create a copy of an Oracle table without copying the data?
上面的任务可以通过两个简单的步骤完成。
步骤1:
CREATE table new_table_name AS(Select * from old_table_name);
上面的 query
创建了一个表的副本(也包含内容)。
要获取结构,请使用删除表的内容。
第2步:
DELETE * FROM new_table_name.
希望这能解决您的问题。并感谢之前的帖子。给了我很多见识。
truncate
版本效率低。除了为所有数据分配范围外,您并没有通过删除来释放它们,因此除非表增长到旧大小,否则您可能会浪费空间。并且您在插入和删除时都生成撤消/重做。吉姆的回答非常简单地避免了所有这些。