Roll back Update or delete data Through Flashback query - sql

I have done some changes and commited but i want to roll back those changes through Flashback query.
Can you please help me how to do this?
I am using Oracle 11g Version.
From below tables i have deleted the data..Now i want to revert back those records..
Customer,
Address,
Employee,
Alignemnt
Many Thanks for your help.
Sunitha.

There are two things,
1.Flashback by SCN
SELECT column_list
FROM table_name
AS OF SCN scn_number;
2.Flashback by TIMESTAMP
SELECT column_list
FROM table_name
AS OF TIMESTAMP TO_TIMESTAMP('the timestamp value');
To get current_scn and systimestamp, query :
SELECT current_scn, SYSTIMESTAMP
FROM v$database;
Update Example as requested by OP.
To flashback the table to the old scn, use FLASHBACK TABLE..TO SCN clause.
SQL> DROP TABLE string_ex PURGE;
Table dropped.
SQL> CREATE TABLE string_ex (sl_ps_code VARCHAR2(20) );
Table created.
SQL> INSERT INTO string_ex (sl_ps_code) VALUES ('AR14ASM0002');
1 row created.
SQL> INSERT INTO string_ex (sl_ps_code) VALUES ('AR14SFT0018');
1 row created.
SQL> INSERT INTO string_ex (sl_ps_code) VALUES ('AR14SFT0019');
1 row created.
SQL> INSERT INTO string_ex (sl_ps_code) VALUES ('AR14SFT0062');
1 row created.
SQL> COMMIT;
Commit complete.
SQL> SELECT current_scn, SYSTIMESTAMP FROM v$database;
CURRENT_SCN SYSTIMESTAMP
-------------------- --------------------------------------------
13818123201277 29-OCT-14 03.02.17.419000 PM +05:30
SQL> SELECT current_scn, SYSTIMESTAMP FROM v$database;
CURRENT_SCN SYSTIMESTAMP
-------------------- --------------------------------------------
13818123201280 29-OCT-14 03.02.22.785000 PM +05:30
SQL> SELECT current_scn, SYSTIMESTAMP FROM v$database;
CURRENT_SCN SYSTIMESTAMP
-------------------- --------------------------------------------
13818123201282 29-OCT-14 03.02.26.781000 PM +05:30
SQL> SELECT * FROM string_ex;
SL_PS_CODE
---------------
AR14ASM0002
AR14SFT0018
AR14SFT0019
AR14SFT0062
SQL>
I have four rows in the table.
SQL> ALTER TABLE string_ex ENABLE ROW MOVEMENT;
Table altered.
SQL>
Row movement is required.
SQL> DELETE FROM string_ex WHERE ROWNUM =1;
1 row deleted.
SQL>
SQL> COMMIT;
Commit complete.
SQL>
SQL> SELECT * FROM string_ex;
SL_PS_CODE
---------------
AR14SFT0018
AR14SFT0019
AR14SFT0062
I deleted a row now and committed the changes.
SQL> FLASHBACK TABLE string_ex TO SCN 13818123201277;
Flashback complete.
Flashback is complete
SQL> SELECT * FROM string_ex;
SL_PS_CODE
---------------
AR14ASM0002
AR14SFT0018
AR14SFT0019
AR14SFT0062
SQL>
I now have my table to old state and the row is back

Related

Inserting date&time, but only date is inserted

I'm trying to insert in a table the date and the time,but at the end only the date is insrted.
here's the code:
create table myDate(date_value Date PRIMARY KEY );
INSERT INTO myDate(date_value ) VALUES (to_date('14/09/2010 18:00','dd/mm/yyyy hh24:mi'));
And I get only 14/09/2010 stocked in the table myDate.What's the problem(is there a way to do that without timestamp)?
I think it worth noting that an alternatives to setting the session NLS parameter is the explicit use of the to_char function. I prefer the to_char because it leaves no doubt to anyone reading the code. Reliance on NLS can be iffy because it can be set at different levels. Besides, if you don't explicitly use to_char, oracle will still call it in the background, using the controlling setting of NLS_DATE_FORMAT.
SQL> -- create table
SQL> Create table mytest (dob date);
Table created.
Elapsed: 00:00:00.08
SQL> insert into mytest values (sysdate);
1 row created.
Elapsed: 00:00:00.03
SQL> commit;
Commit complete.
Elapsed: 00:00:00.00
SQL> select dob nls_default,
2 to_char(dob,'dd-mm-yyyy') dob1,
3 to_char(dob,'yyyy-mm-dd') dob2,
4 to_char(dob,'dd-mm-yyyy hh24:mi:ss') dob3
5 from mytest;
NLS_DEFAU DOB1 DOB2 DOB3
--------- ---------- ---------- -------------------
11-DEC-20 11-12-2020 2020-12-11 11-12-2020 11:45:31
1 row selected.
Elapsed: 00:00:00.03
SQL> drop table mytest purge;
Table dropped.
For more on the subject, see this article.
Depending on the tool you are using is most likely a display issue.
you might want to try something like this
alter session set nls_date_format = 'DD-MON-YYYY HH12:MI:SS PM';
This will alter your sesssion to display the date with full timestamp.
I use oracle sql developer https://www.oracle.com/database/technologies/appdev/sqldeveloper-landing.html
If I don't set the date to my session while I'm writing a query I may see an unexpected date format.
Let us know if that is the case for you as well.

NULL Date field is populated with SYSDATE by default

I am running a query on clocking data for my company. I have a query with 2 fields: CLOCK_IN1 and CLOCK_OUT1. When I run the query I see the proper CLOCK_IN1 but the CLOCK_OUT1 is being populated with a date near SYSDATE. CLOCK_OUT1 is NULL in the database and it's replacing the NULL with this date.
Is there a setting that populates a date when it's NULL?
There's either
a DEFAULT value applied to that column, or
a database trigger that does it.
This is how the first works:
SQL> create table test
2 (clock_in1 date,
3 clock_out1 date default sysdate
4 );
Table created.
SQL> insert into test (clock_in1) values (date '2020-08-23');
1 row created.
SQL> alter session set nls_date_format = 'dd.mm.yyyy hh24:mi:ss';
Session altered.
SQL> select sysdate from dual;
SYSDATE
-------------------
03.11.2020 20:23:03
SQL> select * from test;
CLOCK_IN1 CLOCK_OUT1
------------------- -------------------
23.08.2020 00:00:00 03.11.2020 20:22:48
SQL>
And this is the second:
SQL> drop table test;
Table dropped.
SQL> create table test
2 (clock_in1 date,
3 clock_out1 date
4 );
Table created.
SQL> create or replace trigger trg_bi_test
2 before insert on test
3 for each row
4 begin
5 :new.clock_out1 := nvl(:new.clock_out1, sysdate);
6 end;
7 /
Trigger created.
SQL> insert into test (clock_in1) values (date '2020-08-23');
1 row created.
SQL> select * from test;
CLOCK_IN1 CLOCK_OUT1
------------------- -------------------
23.08.2020 00:00:00 03.11.2020 20:24:23
SQL>
How to "fix" it?
SQL> alter table test modify clock_out1 default null;
Table altered.
SQL>
As of the trigger, well ... it depends on what it is doing, but - removing a line that sets column value would do.

Create Auto Sequence text and number in oracle 11g

How I do create column ID with value JASG1?
I am only find example like this :
select 'JASG'||to_char(mtj_id_seq.nextval) from talend_job
Although what you wrote probably works (if there's a sequence named MTJ_ID_SEQ, you have a privilege to select from it; the same goes for the TALEND_JOB table), I'd say that it isn't what you should use.
Here's why: I'll create a table and a sequence. Table will be pre-populated with some IDs (just to put something in there).
SQL> create sequence mtj_id_seq;
Sequence created.
SQL> create table talend_job as
2 select rownum id from dept;
Table created.
SQL> select * from talend_job;
ID
----------
1
2
3
4
OK; 4 rows so far. Now, run your SELECT:
SQL> select 'JASG'||to_char(mtj_id_seq.nextval) from talend_job;
'JASG'||TO_CHAR(MTJ_ID_SEQ.NEXTVAL)
--------------------------------------------
JASG1
JASG2
JASG3
JASG4
SQL> select 'JASG'||to_char(mtj_id_seq.nextval) from talend_job;
'JASG'||TO_CHAR(MTJ_ID_SEQ.NEXTVAL)
--------------------------------------------
JASG5
JASG6
JASG7
JASG8
SQL>
See? You didn't get only 1 JASGx value, but as many as number of rows in the TALEND_JOB table. If there was a million rows, you'd get a million JASGx rows as well.
Therefore, maybe you meant to use DUAL table instead? E.g.
SQL> select 'JASG'||to_char(mtj_id_seq.nextval) from dual;
'JASG'||TO_CHAR(MTJ_ID_SEQ.NEXTVAL)
--------------------------------------------
JASG9
SQL> select 'JASG'||to_char(mtj_id_seq.nextval) from dual;
'JASG'||TO_CHAR(MTJ_ID_SEQ.NEXTVAL)
--------------------------------------------
JASG10
SQL>
See? Only one value.
Also, notice that sequences will provide unique values, but you can't rely on them being gapless.
As you mentioned "how to create column ID" - one option is to use a trigger. Here's an example:
SQL> create table talend_job (id varchar2(20), name varchar2(20)
Table created.
SQL> create or replace trigger trg_bi_tj
2 before insert on talend_job
3 for each row
4 begin
5 :new.id := 'JASG' || mtj_id_seq.nextval;
6 end;
7 /
Trigger created.
Let's insert some names; IDs should be auto-populated by the trigger:
SQL> insert into talend_job (name) values ('littlefoot');
1 row created.
SQL> insert into talend_job (name) values ('Ishak');
1 row created.
SQL> select * From talend_job;
ID NAME
-------------------- --------------------
JASG11 littlefoot
JASG12 Ishak
SQL>
OK then; now you have some more info - read and think about it.
By the way, what is the "compiler-errors" tag used for? Did you write any code and it failed? Perhaps you'd want to share it with us.

Is commit necessary after DML operation on table using simple sql query?

Is it necessary to run the COMMIT command after a DML operation in SQL Developer? For example, I performed the following UPDATE query:
UPDATE TAB1
SET TBX_TYP='ZX'
WHERE TBX_TYP IN(SELECT TBX_TYP
FROM(
SELECT DISTINCT TBX_TYP
FROM TAB1
ORDER BY 1 )
WHERE ROWNUM=1);
Then when I tried filtering columns, I found that nothing was updated.
The COMMIT instruction is necessary if you want you changes will be available for other users/connections, for example:
Session1:
SQL> conn hr/hr
Connected.
SQL> truncate table ttt;
Table truncated.
SQL> desc ttt;
Name Null? Type
----------------------------------------- -------- ----------------------------
COL1 NOT NULL VARCHAR2(20 CHAR)
SQL> insert into ttt values('one');
1 row created.
SQL> select col1 from ttt;
COL1
--------------------
one
So new data is available in current session.
Session2:
SQL> conn hr/hr
Connected.
SQL> select col1 from ttt;
no rows selected
But another session can't see this data. So let's commit it:
Session1:
SQL> commit;
Commit complete.
Session2:
SQL> /
COL1
--------------------
one
Now this value is available for both sessions.
But commit also is necessary to store data in you data files.
For example let's add a new row to the ttt table but don't commit it:
Session1:
SQL> insert into ttt values('two');
1 row created.
SQL> select col1 from ttt;
COL1
--------------------
one
two
Then let's shutdown the database abnormally and the start it again
Session2:
SQL> conn / as sysdba
Connected.
SQL> shutdown abort
ORACLE instance shut down.
SQL> startup
ORACLE instance started.
Total System Global Area 1068937216 bytes
Fixed Size 2260048 bytes
Variable Size 616563632 bytes
Database Buffers 444596224 bytes
Redo Buffers 5517312 bytes
Database mounted.
Database opened.
SQL>
Then reconnect Session1 and look at the ttt table:
SQL> conn hr/hr
Connected.
SQL> select col1 from ttt;
COL1
--------------------
one
As you can see, the database doesn't store uncommited data in its data files.
Add Commit after every DML(update, delete, insert) command.

How to find the timestamp of when last commit statement was issued?

I looked up this on the Internet and most discussions were about finding the time of last change made. In my case, I want to find the timestamp of when a COMMIT statement was issued for the last, by any user (schema).
Is there any particular way to query this?
If all you need to know, is whether the current SQL*Plus session has an open transaction, you can do that by selecting TADDR from V$SESSION.
Example:
SQL> create table testme(a number);
Table created.
SQL> select taddr from v$session where sid=(select sid from v$mystat where rownum=1);
TADDR
----------------
SQL> insert into testme values(1);
1 row created.
SQL> select taddr from v$session where sid=(select sid from v$mystat where rownum=1);
TADDR
----------------
0000007F50F86420
SQL> commit;
Commit complete.
SQL> select taddr from v$session where sid=(select sid from v$mystat where rownum=1);
TADDR
----------------
SQL>
IF TADDR is null, then there is no current transaction.
Hope that helps.