How can I create a copy of an Oracle table without copying the data? - sql

I know the statement:
create table xyz_new as select * from xyz;
Which copies the structure and the data, but what if I just want the structure?

Just use a where clause that won't select any rows:
create table xyz_new as select * from xyz where 1=0;
Limitations
The following things will not be copied to the new table:
sequences
triggers
indexes
some constraints may not be copied
materialized view logs
This also does not handle partitions

I used the method that you accepted a lot, but as someone pointed out it doesn't duplicate constraints (except for NOT NULL, I think).
A more advanced method if you want to duplicate the full structure is:
SET LONG 5000
SELECT dbms_metadata.get_ddl( 'TABLE', 'MY_TABLE_NAME' ) FROM DUAL;
This will give you the full create statement text which you can modify as you wish for creating the new table. You would have to change the names of the table and all constraints of course.
(You could also do this in older versions using EXP/IMP, but it's much easier now.)
Edited to add
If the table you are after is in a different schema:
SELECT dbms_metadata.get_ddl( 'TABLE', 'MY_TABLE_NAME', 'OTHER_SCHEMA_NAME' ) FROM DUAL;

create table xyz_new as select * from xyz where rownum = -1;
To avoid iterate again and again and insert nothing based on the condition where 1=2

Using sql developer select the table and click on the DDL tab
You can use that code to create a new table with no data when you run it in a sql worksheet
sqldeveloper is a free to use app from oracle.
If the table has sequences or triggers the ddl will sometimes generate those for you too. You just have to be careful what order you make them in and know when to turn the triggers on or off.

You can do this
Create table New_table as select * from Old_table where 1=2 ;
but be careful
The table you create does not have any Index, PK and so on like the 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;

Simply write a query like:
create table new_table as select * from old_table where 1=2;
where new_table is the name of the new table that you want to create and old_table is the name of the existing table whose structure you want to copy, this will copy only structure.

SELECT * INTO newtable
FROM oldtable
WHERE 1 = 0;
Create a new, empty table using the schema of another. Just add a WHERE clause that causes the query to return no data:

WHERE 1 = 0 or similar false conditions work, but I dislike how they look. Marginally cleaner code for Oracle 12c+ IMHO is
CREATE TABLE bar AS
SELECT *
FROM foo
FETCH FIRST 0 ROWS ONLY;
Same limitations apply: only column definitions and their nullability are copied into a new table.

If one needs to create a table (with an empty structure) just to EXCHANGE PARTITION, it is best to use the "..FOR EXCHANGE.." clause. It's available only from Oracle version 12.2 onwards though.
CREATE TABLE t1_temp FOR EXCHANGE WITH TABLE t1;
This addresses 'ORA-14097' during the 'exchange partition' seamlessly if table structures are not exactly copied by normal CTAS operation. I have seen Oracle missing some of the "DEFAULT" column and "HIDDEN" columns definitions from the original table.
ORA-14097: column type or size mismatch in ALTER TABLE EXCHANGE
PARTITION
See this for further read...

you can also do a
create table abc_new as select * from abc;
then truncate the table abc_new. Hope this will suffice your requirement.

Using pl/sql developer you can right click on the table_name either in the sql workspace or in the object explorer, than click on "view" and than click "view sql" which generates the sql script to create the table along with all the constraints, indexes, partitions etc..
Next you run the script using the new_table_name

copy without table data
create table <target_table> as select * from <source_table> where 1=2;
copy with table data
create table <target_table> as select * from <source_table>;

In other way you can get ddl of table creation from command listed below, and execute the creation.
SELECT DBMS_METADATA.GET_DDL('TYPE','OBJECT_NAME','DATA_BASE_USER') TEXT FROM DUAL
TYPE is TABLE,PROCEDURE etc.
With this command you can get majority of ddl from database objects.

Create table target_table
As
Select *
from source_table
where 1=2;
Source_table is the table u wanna copy the structure of.

create table xyz_new as select * from xyz;
-- This will create table and copy all data.
delete from xyz_new;
-- This will have same table structure but all data copied will be deleted.
If you want to overcome the limitations specified by answer:
How can I create a copy of an Oracle table without copying the data?

The task above can be completed in two simple steps.
STEP 1:
CREATE table new_table_name AS(Select * from old_table_name);
The query above creates a duplicate of a table (with contents as well).
To get the structure, delete the contents of the table using.
STEP 2:
DELETE * FROM new_table_name.
Hope this solves your problem. And thanks to the earlier posts. Gave me a lot of insight.

Related

"create table new_table as select * from old_table" will give the table structure as old_table to new_table?

I have a table old_table (In oracle 10g)
I have to copy entire data of old_table into new_table.
At that moment, I will use
create table new_table
as
select * from old_table
Will this command create a table exactly like old_table?
For example, if old_table have some indexes on some columns.
If I use the above command, then, the new_table also have same indexes?
It will only create table with default settings and same structure (same columns and column types) as original table. It will not create any indexes, constraints, grants, triggers and any other objects dependent on the original table.
You can try this
create table new_table as select * from old_table
where 1=2;
It doesn't duplicate constraints (except for NOT NULL, I think).
A more advanced method if you want to duplicate the full structure is:
SET LONG 5000
SELECT dbms_metadata.get_ddl( 'TABLE', 'MY_TABLE_NAME' ) FROM DUAL;
This will give you the full create statement text which you can modify as you wish for creating the new table. You would have to change the names of the table and all constraints of course.
(You could also do this in older versions using EXP/IMP, but it's much easier now.)
If the table you are after is in a different schema:
SELECT dbms_metadata.get_ddl( 'TABLE', 'MY_TABLE_NAME', 'OTHER_SCHEMA_NAME' ) FROM DUAL;

The command that could copy the table structure, all constraints and priviledge in Oracle

I am new to oracle. I would like to ask if there exist one single command that could copy table a to table b such that table b would have the same data, same structure and same access priviledge as table a? I would like to make a duplicate of a table which contain the same behavior.
Someone please correct me if I am wrong, but I don't think you can copy it with privileges/indexes as it is. That might be becasuse you need to give a new name for the index,primary key etc, and the database will not know what name needs to be given to these. So you can do this.
Run this to get the DDL of the table you want and then replace it with new table name. (my source table is TZ_TEST and I will create TZ_TEST_NEW. (Thanks to this answer for get_ddl command)
select replace(
(SELECT dbms_metadata.get_ddl( 'TABLE', 'TZ_TEST' ) FROM DUAL),
'TZ_TEST',
'TZ_TEST_NEW')
from dual
Execute the DDL
Use this to get grant permissions
select replace(
(select DBMS_METADATA.GET_DEPENDENT_DDL('OBJECT_GRANT','TZ_TEST') FROM DUAL),
'TZ_TEST',
'TZ_TEST_NEW') from dual
Similarly use DBMS_METADATA to get constraints/index etc. Execute these statmetns.
Insert data
insert into TZ_TEST_NEW
select * from TZ_TEST
Please remember that if you have an auto generated primary key, then while inserting data, you need to exclude that column from insert and select statments.
Anyone please feel free to add if I missed something.
Also we can create a procedure which can so all this but you need to be careful with all the steps. So once you do it couple of times and it works, we can create a procedure for it.
If you are using TOAD for Oracle, then select the table name and press F4. Then select script tab in the describe window.
This will generate the table script. You just need to use Search/Replace to change the table name and execute the script.
The newly created table will contain the same behavior.
I would do it in two steps:
Use CTAS i.e. create table as select .. to first create a copy of the table with new name with the data. You could also use PARALLEL and NOLOGGING feature to increase the performance.
For example,
create table t parallel 4 nologging as select * from emp;
Get the associated structures like indexes, constraints etc. using DBMS_METADATA.GET_DEPENDENT_DDL and execute it. But, you need to first replace the table_name to your new table_name as you have created in step 1.
CTAS would be much faster than traditional insert.

Fastest way to copy a table in mysql?

I want to copy a table in MySQL. What is the fastest way? Like this?
CREATE TABLE copy LIKE original;
INSERT INTO copy SELECT * FROM original;
or
CREATE TABLE copy SELECT * FROM original;
ALTER TABLE copy ADD PRIMARY KEY (id);
or is there another way?
EDIT: I'm worried about the indexes being re-created, how does mysql proceed executing these statements?
PS. can't use command-line tools like mysqldump, must be on-the-fly.
This copies the structure of the table immediately, but not the data:
CREATE TABLE copy LIKE original;
This creates all the indexes the original table had.
It works this way in mysql 5.1.39.
The fastest way using MyISAM tables while preserving indexes) and maybe other storage engines is:
CREATE TABLE copy LIKE original;
ALTER TABLE copy DISABLE KEYS;
INSERT INTO copy SELECT * FROM original;
ALTER TABLE copy ENABLE KEYS;
You want to disable your keys for your database load and then recreate the keys at the end.
Similarly, for InnoDB:
SET unique_checks=0; SET foreign_key_checks=0;
..insert sql code here..
SET unique_checks=1; SET foreign_key_checks=1;
(As pointed out in the comments.)
From the manual:
"CREATE TABLE ... SELECT does not automatically create any indexes for you. This is done intentionally to make the statement as flexible as possible. If you want to have indexes in the created table, you should specify these before the SELECT statement: "
CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;
You can specify indices and data types (to avoid datatype conversion) in with both CREATE TABLE LIKE and CREATE TABLE SELECT. Which one is faster will depend on your setup.
To copy with indexes and triggers do these 2 queries:
CREATE TABLE newtable LIKE oldtable;
INSERT newtable SELECT * FROM oldtable;
To copy just structure and data use this one:
CREATE TABLE tbl_new AS SELECT * FROM tbl_old;
Does create table mynewtable (select * from myoldtable) work in mysql? If so you can try it too.
Best way to copy structure and all entries from one table to another table (by creating new table) is this query...
CREATE TABLE new_table LIKE old_table;
INSERT INTO new_table
SELECT * FROM old_table;
Try SELECT INTO, and use a variable as a go-between.
You'll have to create the receiving table, first, to have the same structure as the source table.
Best thing is, it's internal so it's fast. You'll lose your indexes, though.
if you are using MyISAM you can also copying and renaming the induvidual files .
.MYD, .MYI, .FRM files in the backend
Maybe you could take a look at SHOW CREATE TABLE.
Steps to take:
Go to phpmyadmin
Go to SQL
Execute this query
SHOW CREATE TABLE `the_old_table`;
Click options
Check "Full texts" and press Go.
The result is a full CREATE TABLE statement. Edit the query until you are happy.
Resource:
http://dev.mysql.com/doc/refman/5.7/en/show-create-table.html
CREATE TABLE copy SELECT * FROM original;
Is a fast way but maybe not the quickest cause of indexes.

dynamically create table statement in sql

how to dynamically create a table with same columns as that of previous table. in sql
select * into new_table from table where 1 = 0
select * into new_table from table
Thats works in SQL2005
I believe that both of the above answers will work, but since you don't need the data and you just need the format, I would do the following:
select * into new_table from table
TRUNCATE new_table; -- I'm sure you know this, but just in case someone is new and doesn't, truncate leaves the table structure and removes all of the data.

Create a replica of a sql table

I need a query to create a table which is the exact replica but with different table name and without any data from the source table using a sql query!
You can try this
SELECT * INTO Table_Copy
FROM Table
where 1=2
It will create a empty table with the same structure.
SQL Server Management Studio
Object Explorer
Connect -> Your server
Databases -> Choose Database
Tables
Right Click Your Table
Script Table as -> Create To -> New Query Editor Window
Jonathan has it (upvoted), and you should probably go with that because it's more portable. I normally use something similar:
SELECT TOP 0 * INTO [New_Table] FROM [Old_Table]
I think this better expresses what you're doing, but I like Jonathan's because 'TOP 0' is SQL Server specific, and so his is more portable.
For MySQL, you can call SHOW CREATE TABLE table_name;
It will display a CREATE TABLE query. Simply change the table name in that query and you're good to go.
http://dev.mysql.com/doc/refman/5.1/en/show-create-table.html
If you use Postgresql:
CREATE TABLE LIKE table_name
http://www.postgresql.org/docs/8.1/static/sql-createtable.html
SELECT * INTO Table_Copy
FROM Table
where 1=2
This worked very well, when i tried to create a replica of the table without any data's.
SELECT * INTO Table_Copy
FROM Table
This will create a replica with the data's too.
This can help you:
CREATE TABLE foo AS SELECT...
Read more here
select * into newtablename from sourcetablename
go
truncate newtablename
go
That will result in an exact copy but it also copies the data at first which you remove with the truncate statement.
create table <new table name> as select * from <old tale name from which you would like to extract data>
It will create a new table with a different name but will copy all existing data from the old table to new table.
in postgres you can use INHERITS or LIKE keyword to make replica of a table(only copies structure of the table)
CREATE TABLE client_new (LIKE client);
or
CREATE TABLE client_new () INHERITS (client)
Use of INHERITS creates a persistent relationship between the new child table and its parent table(s). Schema modifications to the parent(s) normally propagate to children as well, and by default the data of the child table is included in scans of the parent(s).
LIKE clause specifies a table from which the new table automatically copies all column names, their data types, and their not-null constraints.Unlike INHERITS, the new table and original table are completely decoupled after creation is complete. Changes to the original table will not be applied to the new table, and it is not possible to include data of the new table in scans of the original table.