Teradata: How to back up a table that uses an identity column? - sql

In Teradata, the way I've been doing backups for tables is like this:
create table xxx_bak as xxx with data
Works great, but I have just discovered that this doesn't work for tables with identity columns.
I need a backup method that can duplicate a table with its data intact so that I can roll it back in case I mess up some data.

After over a year and a half, I've finally found a slick solution to this issue:
create table mydb.mytablebackup as
(select * from (select * from mydb.mytable) x)
with data;
Be sure to qualify the innermost subquery or it won't work.

If you just want a copy of the table, you can create one with the same structure but without making the key column an identity column. You can then insert into it from the original table. However, you wouuldn't be able to insert back into the old table from the backup while retaining the same keys.
The way to make a backup that you can later restore with the same keys is to use the archive/restore tool ARCMAIN.
Backup like this:
logon my_server/my_user, my_password;
archive data tables (my_database.my_table), release lock, file=backup_file;
Restore like this:
logon my_server/my_user, my_password;
restore data tables (my_database.my_table), release lock, file=backup_file;

This involves 3 steps:
1. SHOW TABLE orig_Table; (*Get the DDL*)
2. Replace orig_Table with bkp_Table name
3. INSERT INTO bkp_Table SELECT * FROM orig_Table;

Related

identity id column in sql table doesn't start at 1

I ran a delete script to delete all rows that had an id greater than 0 to clear the table and now when I try to add rows to the table, the id starts off where it left off from before. How can I delete the info in the table so the id starts off at 1 again?
Delete statement doesnt reset the identity value. Use Truncate table command if you want identity value to be reset. something like this..
TRUNCATE TABLE Table_Name
This will empty the table and reset the identity value.
Only use TRUNCATE when you want all the rows to be deleted. As it does not allow you to use WHERE clause.
I don't think that is possible in the same table. Which database are you using? In previous versions of MS Access compacting the database used to work but not any more. I don't think SQL Server allows that either. The only way is to copy the records from this table to a new table, delete the old table and rename the new table to the old table name.
In MS-SQL you can have a play with DBCC CHECKIDENT (yourtable, reseed, 0)

How to copy structure and contents of a table, but with separate sequence?

I'm trying to setup temporary tables for unit-testing purposes. So far I managed to create a temporary table which copies the structure of an existing table:
CREATE TEMP TABLE t_mytable (LIKE mytable INCLUDING DEFAULTS);
But this lacks the data from the original table. I can copy the data into the temporary table by using a CREATE TABLE AS statement instead:
CREATE TEMP TABLE t_mytable AS SELECT * FROM mytable;
But then the structure of t_mytable will not be identical, e.g. column sizes and default values are different. Is there a single statement which copies everything?
Another problem with the first query using LIKE is that the key column still references the SEQUENCE of the original table, and thus increments it on insertion. Is there an easy way to create the new table with its own sequence, or will I have to set up a new sequence by hand?
I'm using the following code to do it:
CREATE TABLE t_mytable (LIKE mytable INCLUDING ALL);
ALTER TABLE t_mytable ALTER id DROP DEFAULT;
CREATE SEQUENCE t_mytable_id_seq;
INSERT INTO t_mytable SELECT * FROM mytable;
SELECT setval('t_mytable_id_seq', (SELECT max(id) FROM t_mytable), true);
ALTER TABLE t_mytable ALTER id SET DEFAULT nextval('t_my_table_id_seq');
ALTER SEQUENCE t_mytable_id_seq OWNED BY t_mytable.id;
Postgres 10 or later
Postgres 10 introduced IDENTITY columns conforming to the SQL standard (with minor extensions). The ID column of your table would look something like:
id integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY
Syntax in the manual.
Using this instead of a traditional serial column avoids your problem with sequences. IDENTITY columns use exclusive, dedicated sequences automatically, even when the specification is copied with LIKE. The manual:
Any identity specifications of copied column definitions will only be
copied if INCLUDING IDENTITY is specified. A new sequence is created
for each identity column of the new table, separate from the sequences
associated with the old table.
And:
INCLUDING ALL is an abbreviated form of INCLUDING DEFAULTS INCLUDING IDENTITY INCLUDING CONSTRAINTS INCLUDING INDEXES INCLUDING STORAGE INCLUDING COMMENTS.
The solution is simpler now:
CREATE TEMP TABLE t_mytable (LIKE mytable INCLUDING ALL);
INSERT INTO t_mytable TABLE mytable;
SELECT setval(pg_get_serial_sequence('t_mytable', 'id'), max(id)) FROM tbl;
As demonstrated, you can still use setval() to set the sequence's current value. A single SELECT does the trick. pg_get_serial_sequence()]6 gets the name of the sequence.
db<>fiddle here
Related:
How to reset postgres' primary key sequence when it falls out of sync?
Is there a shortcut for SELECT * FROM?
Creating a PostgreSQL sequence to a field (which is not the ID of the record)
Original (old) answer
You can take the create script from a database dump or a GUI like pgAdmin (which reverse-engineers database object creation scripts), create an identical copy (with separate sequence for the serial column), and then run:
INSERT INTO new_tbl
SELECT * FROM old_tbl;
The copy cannot be 100% identical if both tables reside in the same schema. Obviously, the table name has to be different. Index names would conflict, too. Retrieving serial numbers from the same sequence would probably not be in your best interest, either. So you have to (at least) adjust the names.
Placing the copy in a different schema avoids all of these conflicts. While you create a temporary table from a regular table like you demonstrated, that's automatically the case since temp tables reside in their own temporary schema.
Or look at Francisco's answer for DDL code to copy directly.

Where temp tables are located?

If I create a temporary table using # sign:
SELECT * INTO #temp FROM dbo.table
Where is this table located? I can't find this from tempdb.
Those tables are created in your tempDB - but the table name might not be exactly as you defined.
In my case, I get:
#temp______________________________000000000003
Try this:
SELECT * INTO #temp FROM dbo.table
SELECT * FROM tempdb.sys.tables
You should see an entry for that temp table you've just created....
When you declare a temporary table, SQL Sever adds some additional characters on its name in order to provide a unique system name for it and then it stores it in tempDB in the sysobjects table. Even though you can query the temporary table with its logical name, internally is known with the exact name SQL Server has set.
How are you looking for them?
If you do a select you'll get the data.
But the table is only available in the session, just for the user who created it (you can have global temp tables).
They are stored in temp db.
Local temp tables can be created using hash (#) sign prior to table name.
They are visible only in current connection. When connection is dropped its scope ends as well.
It is possible to create and use local temp table with the same name simultaneously in two different connections.
Read More
http://sqlnetcode.blogspot.com/2011/11/there-is-already-object-named-temp-in.html
I suspect this issue rose from the fact that if you don't right click and refresh the 'Temporary Tables' folder, SSMS will not show you the temp table immediately.

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.

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.