How to restore the data in a Oracle table? - oracle

I did a terrible mistake on my work, I executed an updated query on a oracle table without the 'where' clause and everything changed on this table, I was wondering if there is any way to restore the data on a table. I know I can use Flashback, but Is there another way to do that? If you know how to make a flashback table in oracle, please let me know.
I'm using Oracle 10g R2 10.2.0.1

First, did you commit the change? If not, you can simply issue a rollback to revert your changes.
Assuming that you did commit your changes, are other users modifying the table at the same time? Do you need to preserve the changes that others have made and only revert the changes you made in your transaction? Or can you restore the entire table to a point in time before your changes were made?
If you can restore the entire table to a point in time
FLASHBACK TABLE <<table name>>
TO TIMESTAMP( systimestamp - interval '10' minute )
will return a table to the state it was in 10 minutes ago assuming that the UNDO necessary to do so remains available (so you only have a limited time after making a mistake to be able to flashback that mistake). In order to issue a FLASHBACK TABLE, you also have to make sure that
The table has enabled row movement ALTER TABLE <<table name>> ENABLE ROW MOVEMENT
You must have FLASHBACK privileges on the table or the FLASHBACK ANY TABLE system privilege.

Starting from Oracle9i R2, doesn't require specific rights
Revert updated columns
update <table> t
set (<column1>, <column2>, ...)
= (select <column1>, <column2>, ...
from <table> as of timestamp to_timestamp('2016-07-21 09:39:20', 'YYYY-MM-DD HH:MI:SS') h
where t.<uk> = h.<uk>);
Revert deleted rows
insert into <table>
select * from <table> as of timestamp to_timestamp('2016-07-21 03:30:00', 'YYYY-MM-DD HH:MI:SS')
where <uk> not in
(select t.<uk> from <table> t);
Don't be misleaded with DB timezone and verify current time
select sysdate from dual;

Related

Oracle. Select data from one session but commit it to another. Is it possible?

Probably I ask for the impossible, but I'll ask anyway.
Is there an easy way to select from one Oracle session and then insert/commit into another?
(I guess, technically it could be done with pl/sql procedure calls and PRAGMA AUTONOMUS Transactions, but it would be a hassle)
I have the following scenario:
I run some heavy calculations and update / insert into some tables.
After the process is completed I would like to 'backup' the results
(create table as select or insert into another temp table) and then rollback my current session without loosing the backups.
Here is desired/expected behavior:
Oracle 11g
insert into TableA (A,B,C) values (1,2,3);
select * from TableA
Result: 1,2,3
create table [in another session] TempA
as select * from TableA [in this session];
rollback;
select * from TableA;
Result null
select * from TempA;
Result 1,2,3
Is this possible?
Is there an easy way to select from one Oracle session and then insert/commit into another?
Create a program in a third-party language (C++, Java, PHP, etc.) that opens two connections to the database; they will have different sessions regardless of whether you connect as different users or both the same user. Read from one connection and write to the other connection.
you can insert your "heavy calculation" into a Oracle temp Table .
CREATE GLOBAL TEMPORARY TABLE HeavyCalc (
id NUMBER,
description VARCHAR2(20)
)
ON COMMIT DELETE ROWS;
the trick is that when you commit the transaction all rows are deleted from temporary table.
Then you first insert data into the temp table, copy the result to you backup table and commit the transaction.

oracle flashback feature for tables of a specific user in a database

I am trying to implement a flashback feature in oracle 11g. I have successfully implemented it but it is not restricted to a single user instead, whenever I restore a flashback it affects all the tables/views for all the users. Is there some way to restrict the restoration to a particular user and avoiding the rest.
Example: I have a database "db" and there are 4 users "a,b,c,d" now, I want to restore the flashback such that it only affects user "a"?
Use the command FLASHBACK TABLE instead of FLASHBACK DATABASE to only affect specific tables.
For example:
create table table1(a number) enable row movement;
create table table2(a number) enable row movement;
--Wait one second.
flashback table jheller.table1, jheller.table2 to timestamp systimestamp - interval '1' second;
Keep in mind that table flashback uses UNDO, while database flashback uses flashback logs. Table flashback depends on UNDO retention and is more picky about things like DDL.

Recovering deleted rows from oracle table

Is this possible to recover the deleted rows from oracle table? My data is stored in a table MANUAL_TRANSACTIONS. Schema name is CCO.I have accidentally deleted some 500 Thousands rows in a table and did the commit too. Now I want to recover them.I am using Oracle 11g R2.Thanks
You can recover the details using Oracle Flashback Query.
You could query the contents of the table as of a time before the deletion to find out what data had been lost, and, if appropriate, re-insert the lost data in the database.
Here's the sample query:
select * from MANUAL_TRANSACTION as of timestamp to_timestamp('28-APR-2014 12:30:00', 'DD-MON-YYYY HH:MI:SS') where ' clause based on your deleted data';
Source: http://docs.oracle.com/cd/B19306_01/backup.102/b14192/flashptr002.htm
answers are already given just what i learned form above .
FLASHBACK can only be done by DBA( I guess ) but we can use below query
Insert into MANUAL_TRANSACTIONS
(SELECT * FROM MANUAL_TRANSACTIONS AS OF
TIMESTAMP TO_TIMESTAMP('2018-07-23 06:41:59', 'YYYY-MM-DD HH:MI:SS'));
or you can go for this query for one day records
Insert into MANUAL_TRANSACTIONS
(SELECT * FROM MANUAL_TRANSACTIONS AS OF
TIMESTAMP TO_TIMESTAMP('2018-07-23', 'YYYY-MM-DD'));
select * from MY_TABLE as of timestamp to_timestamp('04-MAY-2017 12:30:00', 'DD-MON-YYYY HH:MI:SS') where ID=1822904; --- 12Hr Clock
Above query works for me. You can even look for 24Hr timeframe using below query
select * from MY_TABLE as of timestamp to_timestamp('04-MAY-2017 13:30:00', 'DD-MON-YYYY HH24:MI:SS') where ID=1822904;
Yes, you can, use flash back query.
Using Oracle Flashback Query (SELECT AS OF)
This assumes that the undo tablespace was big enough, with enough undo retention. If the undo is already freed, you might need to perform a restore and recovery, in a clone database and copy the data to the original database. Also check TSPITR, TableSpace Point In Time Recovery. This is only possible if your database runs in archivelog mode and has a backup available.
If you have backup and Oracle 12c you could use Table Point In Time Recovery (PITR):
RECOVER TABLE 'SCHEMA'.'TAB_NAME'
UNTIL TIME xxxxyyy
AUXILIARY DESTINATION '/u01/aux'
REMAP TABLE 'SCHEMA'.'TAB_NAME':'TAB_NAME_PREV';
Your data at that point in time will be available:
SELECT * FROM SCHEMA.TAB_NAME_PREV;
INSERT INTO TABLE_NAME(SELECT * FROM TABLE_NAME AS OF TIMESTAMP(SYSDATE - 4/24)
I know this is too late for the answer, after long search about how to recovery and restore tables in oracle I finally found a good way to restore by using restore point, according to Pro Oracle Database 12C Administration book, before any action into your table you could use restore point by using following lines:
CREATE RESTORE POINT <your_key_point_name>;
for recovery table with restore point you can use :
FLASHBACK TABLE <[your_schema.]your_table_name> TO RESTORE POINT <your_key_point_name>;
beside this all of above answers "about recovering using FLASHBACK" forgot to consider two key points:
for using FLASHBACK recycle bin mode must be enabled
before any row recovery using FLASHBACK , row movement in your table must be enabled (with ALTER TABLE <[your_schema.]your_table_name> enable ROW MOVEMENT). According to oracle documents link:
Before you can use Flashback Table, you must ensure that row movement is enabled on the table to be flashed back, or returned to a previous state.
FLASHBACK TABLE <TABLE_NAME> TO TIMESTAMP(TO_DATE('27-APR-2014 23:59:59','DD-MON-YYYY HH24: MI: SS'));
Restores the data in the table to the given time(provided the table was not truncated).
In your case:
FLASHBACK TABLE MANUAL_TRANSACTIONS TO TIMESTAMP(TO_DATE('27-APR-2014 23:59:59','DD-MON-YYYY HH24: MI: SS'));
Use this query,
Insert into MANUAL_TRANSACTIONS
(SELECT * FROM MANUAL_TRANSACTIONS AS OF
TIMESTAMP TO_TIMESTAMP('2014-04-27 11:59:59 PM', 'YYYY-MM-DD HH:MI:SS PM'))
There are some options:
Flashback Query as
create table before_delete as select * from Table as of TIMESTAMP XX;
Logminer if Oracle supplement log is enabled , you can get undo sql for your delete statement
-- switch again logfile to get a minimal redo activity
alter system switch logfile;
-- mine the last written archived log
exec dbms_logmnr.add_logfile('archivelog/redologfile', options => dbms_logmnr.new);
exec dbms_logmnr.start_logmnr(options => dbms_logmnr.dict_from_online_catalog);
select operation, sql_redo from v$logmnr_contents where seg_name = 'EMP';
Oracle PRM-DUL will be last option. Even deleted row piece in Oracle block is always just marked row flag with deleted mask, the row piece still can be read via scan Oracle data block . PRM-DUL can scan the whole table , find out every record/row piece marked deleted and write out to flat file.
what you may try is :
flashback query, available from oracle 10g , may failed with ora-01555 snapshot too old
redo logminer , mine redo and may find undo sql
prm-dul tool ( a commercial recovery tool for oracle), which can scan oracle block and find even deleted row piece

Oracle Accidental Deletion

I deleted many table's records accidentally on Oracle 10g, and I have no backup, noarchivelog mode, not open flashback.
Is it possible to restore data? If yes, how shall I do?
How long ago did you delete the data? If you deleted the data a little less than an hour ago, for example, can you run this query and see if the data is still in UNDO?
SELECT *
FROM some_table AS OF TIMESTAMP systimestamp - INTERVAL '1' hour

Obtain Oracle 11g partitioning interval by direct system table query

I've got a table which is partitioned on a NUMBER variable in Oracle 11g, with the INTERVAL set to 1. On our development system I can execute
SELECT DBMS_METADATA.GET_DDL('TABLE', 'TABLE_NAME', 'SCHEMA_NAME') FROM DUAL;
to verify that the table is partitioned as expected, which it is. On our production box, however, developers aren't allowed to modify data or to run any procedures, and thus I can't use DBMS_METADATA.GET_DDL to get the DDL and, hence, to determine the INTERVAL set on the production DB. Could someone provide an idea of how to find the value used in the INTERVAL clause when the production table was built by querying system tables or views? Thanks.
Get select access to dba_part_tables (for 11gr2):
select interval from dba_part_tables where table_name = 'SOME_TABLE' and owner = 'SOME_OWNER';

Resources