How to swap table name in oracle - oracle

I have 2 oracle tables that are identical in definition just different in partition definition. I want to test one table vs another table design. Is there a way to swap the table name? I don't want to drop a table because they are big and takes a long time to load data into them.

Use a synonym that points to the real tables.
For example,
CREATE OR REPLACE SYNONYM partition_test FOR partition_table1;
Test partition_table1, e.g. select pt.* from partition_test pt;
CREATE OR REPLACE SYNONYM partition_test FOR partition_table2;
Test partition_table2, e.g. select pt.* from partition_test pt;
Notice the test code is then same each time.
When you're done testing, drop the synonym.
DROP SYNONYM partition_test;

Just rename them. For example, if you have TABLE_A, rename it to TABLE_A_TEMP. Then rename TABLE_B to TABLE_A. Then rename TABLE_A_TEMP to TABLE_B.
To rename, you'll have to issue
alter table table_name rename to new_table_name;

A third method would be to use a view. Let's say your "real" table names are TABLE_A and TABLE_B. Create a view, MY_DATA_VIEW (or whatever), and have it point to whichever table you want it to point to:
CREATE OR REPLACE VIEW TEST_VIEW AS SELECT * FROM TABLE_A;
or
CREATE OR REPLACE VIEW TEST_VIEW AS SELECT * FROM TABLE_B;
Share and enjoy.

Related

Restore backup table data to old one

I made some changes in my tables and I need to make backup of tables which I use something like
CREATE TABLE supplier_invoice_rows_backup
AS
SELECT * FROM supplier_invoice_rows
I made changes and I need to return data from supplier_invoice_rows_backup to supplier_invoice_rows
Is there any way to do this ?
Yes there is! Try mysql code below.
RENAME TABLE supplier_invoice_rows_backup TO supplier_invoice_rows;
Or try oracle code.
RENAME supplier_invoice_rows_backup TO supplier_invoice_rows;
An alternative to renaming the table would be to truncate the original table and copy the rows from the 'backup' table:
truncate table supplier_invoice_rows;
insert into supplier_invoice_rows (select * from supplier_invoice_rows_backup);
Or just reverse your original:
drop table supplier_invoice_rows purge;
create table supplier_invoice_rows
as
select * from supplier_invoice_rows_backup;
Or the previously suggested rename. Your response to that suggestion ("but I want to copy") suggests you haven't thought this through. You cannot have two tables with the same name in the same schema. So what do you think is the end result of 'rename table supplier_invoice_rows_backup to supplier_invoice_rows'?

Oracle - Change Table Position [duplicate]

I have a specific scenario where i have to insert two new columns in an existing table in Oracle. I can not do the dropping and recreating the table. So can it be achieved by any means??
Amit-
I don't believe you can add a column anywhere but at the end of the table once the table is created. One solution might be to try this:
CREATE TABLE MY_TEMP_TABLE AS
SELECT *
FROM TABLE_TO_CHANGE;
Drop the table you want to add columns to:
DROP TABLE TABLE_TO_CHANGE;
It's at the point you could rebuild the existing table from scratch adding in the columns where you wish.
Let's assume for this exercise you want to add the columns named "COL2 and COL3".
Now insert the data back into the new table:
INSERT INTO TABLE_TO_CHANGE (COL1, COL2, COL3, COL4)
SELECT COL1, 'Foo', 'Bar', COL4
FROM MY_TEMP_TABLE;
When the data is inserted into your "new-old" table, you can drop the temp table.
DROP TABLE MY_TEMP_TABLE;
This is often what I do when I want to add columns in a specific location. Obviously if this is a production on-line system, then it's probably not practical, but just one potential idea.
-CJ
In 12c you can make use of the fact that columns which are set from invisible to visible are displayed as the last column of the table:
Tips and Tricks: Invisible Columns in Oracle Database 12c
Maybe that is the 'trick' #jeffrey-kemp was talking about in his comment, but the link there does not work anymore.
Example:
ALTER TABLE my_tab ADD (col_3 NUMBER(10));
ALTER TABLE my_tab MODIFY (
col_1 invisible,
col_2 invisible
);
ALTER TABLE my_tab MODIFY (
col_1 visible,
col_2 visible
);
Now col_3 would be displayed first in a SELECT * FROM my_tab statement.
Note: This does not change the physical order of the columns on disk, but in most cases that is not what you want to do anyway. If you really want to change the physical order, you can use the DBMS_REDEFINITION package.
Although this is somewhat old I would like to add a slightly improved version that really changes column order. Here are the steps (assuming we have a table TAB1 with columns COL1, COL2, COL3):
Add new column to table TAB1:
alter table TAB1 add (NEW_COL number);
"Copy" table to temp name while changing the column order AND rename the new column:
create table tempTAB1 as select NEW_COL as COL0, COL1, COL2, COL3 from TAB1;
drop existing table:
drop table TAB1;
rename temp tablename to just dropped tablename:
rename tempTAB1 to TAB1;
You (still) can not choose the position of the column using ALTER TABLE: it can only be added to the end of the table. You can obviously select the columns in any order you want, so unless you are using SELECT * FROM column order shouldn't be a big deal.
If you really must have them in a particular order and you can't drop and recreate the table, then you might be able to drop and recreate columns instead:-
First copy the table
CREATE TABLE my_tab_temp AS SELECT * FROM my_tab;
Then drop columns that you want to be after the column you will insert
ALTER TABLE my_tab DROP COLUMN three;
Now add the new column (two in this example) and the ones you removed.
ALTER TABLE my_tab ADD (two NUMBER(2), three NUMBER(10));
Lastly add back the data for the re-created columns
UPDATE my_tab SET my_tab.three = (SELECT my_tab_temp.three FROM my_tab_temp WHERE my_tab.one = my_tab_temp.one);
Obviously your update will most likely be more complex and you'll have to handle indexes and constraints and won't be able to use this in some cases (LOB columns etc). Plus this is a pretty hideous way to do this - but the table will always exist and you'll end up with the columns in a order you want. But does column order really matter that much?

Creating instances of global temporary table

I created a GTT at schema level
CREATE GLOBAL TEMPORARY TABLE schema1.gtt1
(
col1 type1,
col2 type2,
...
)
ON COMMIT PRESERVE ROWS;
Now I can reference the table from within a PLSQL block/procedure/function very easily:
INSERT INTO schema1.gtt1
select col1, col2, ... from ...;
but what if in the same PLSQL block I want to insert values in another global temporary table (GTT) with the same structure as the one I created?
Do I have to create another GTT, and give it another name even if it has the very same structure (I think it would be awkward)? or can I somehow create multiple instances of a GTT?
Don't know if it's relevant but I'll be joining the GTT's with other tables, within the same PLSQL block.
You have 2 tables, A and B with same structure. (GTT but accessed from same session so we can ignore this)
Your question do I have to insert in both at runtime or can I use only one?
This is a question that only you can answer based on the meaning of what you insert and your need to differentiate the records.
If you need to make the difference between these 2 record sets (what you insert in A and what in B) but you have no key to make this distinction than you would need to: add a new column in structure like "source" or insert into different tables.
There is no "multiple instances" concept of GTT within session so this won't do the trick.

Synonym to point two tables with same name but different suffix?

I am pretty new to oracle and trying to create a synonym to point two different tables on different days. Please see my example below.
I have two tables named table_1 and table _2 and a synonym table. At first i point the synonym to table_1;
CREATE SYNONYM table for schema.table_1;
Next day i would want to point the synonym to table_2. Should i use another statement like
CREATE OR REPLACE SYNONYM table for schema.table_2;
or is there any other way. Could someone help me?
There are numerous options.
Create a database job which will do synonym update by schedule. It may cause troubles for queries which are using the synonym at the time of its replacement.
Create a package with procedures which will hide table switching from application layer.
Create a view to hide table switching based on example select below. Assuming that you are only reading and tables have the same structure.
Don't duplicate tables.
Select for view
SELECT DUMMY
FROM (
SELECT 'X' AS DUMMY, 0 AS SEP FROM DUAL TABLE1
UNION ALL
SELECT 'Y' AS DUMMY, 1 AS SEP FROM DUAL TABLE2)
WHERE
SEP = MOD(EXTRACT(DAY FROM SYSDATE), 2)

The different between TABLE_NAME vs "TABLE_NAME" in Oracle?

I'm a very new Oracle SQL user and I got a problem.
If I create a table with code such as
create table TBL_NAME...
after that I can get data by
select * from TBL_NAME;
However, when I create table with Navicat (just click on button new table), then I have to add "" to table name to access my table, such as:
select * from "TBL_NAME";
So, is there have other type of table? And if I use Navicat to create table, what type of it?
When you specify the name of a table in Oracle without double quotes then Oracle converts that table name to uppercase. But if you specify the name of the table within double-quotes then Oracle will respect the lower-case letters that you may have.
So, as in your example the name of your table is already all upper-case, then there is no difference in specifying or not the double-quotes.
But for example if you create a table like this:
CREATE TABLE "my_table" ....
Then you cannot access it like this:
SELECT * FROM my_table;
as Oracle will convert that select to this:
SELECT * FROM MY_TABLE;
And there is no such table in your system.
In your case with Navicat, it just needs you to specify the name of the table as-is, but don't worry, just put the double-quotes and stick to all upper-case names and you will be fine.

Resources